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'],
95 # Specify linker-script with add_project_link_arguments so that it is not placed
96 # within a linker --start-group/--end-group pair
97 if 'CONFIG_FUZZ' in config_host
98 add_project_link_arguments(['-Wl,-T,',
99 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
100 native: false, language: ['c', 'cpp', 'objc'])
103 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
104 native: false, language: ['c', 'objc'])
105 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
106 native: false, language: 'cpp')
107 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
108 native: false, language: ['c', 'cpp', 'objc'])
110 if targetos == 'linux'
111 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
112 '-isystem', 'linux-headers',
113 language: ['c', 'cpp'])
116 add_project_arguments('-iquote', '.',
117 '-iquote', meson.current_source_dir(),
118 '-iquote', meson.current_source_dir() / 'include',
119 '-iquote', meson.current_source_dir() / 'disas/libvixl',
120 language: ['c', 'cpp', 'objc'])
122 link_language = meson.get_external_property('link_language', 'cpp')
123 if link_language == 'cpp'
124 add_languages('cpp', required: true, native: false)
126 if host_machine.system() == 'darwin'
127 add_languages('objc', required: false, native: false)
130 sparse = find_program('cgcc', required: get_option('sparse'))
133 command: [find_program('scripts/check_sparse.py'),
134 'compile_commands.json', sparse.full_path(), '-Wbitwise',
135 '-Wno-transparent-union', '-Wno-old-initializer',
136 '-Wno-non-pointer-null'])
139 ###########################################
140 # Target-specific checks and dependencies #
141 ###########################################
143 if targetos != 'linux' and get_option('mpath').enabled()
144 error('Multipath is supported only on Linux')
147 m = cc.find_library('m', required: false)
148 util = cc.find_library('util', required: false)
154 emulator_link_args = []
156 if targetos == 'windows'
157 socket = cc.find_library('ws2_32')
158 winmm = cc.find_library('winmm')
160 win = import('windows')
161 version_res = win.compile_resources('version.rc',
162 depend_files: files('pc-bios/qemu-nsis.ico'),
163 include_directories: include_directories('.'))
164 elif targetos == 'darwin'
165 coref = dependency('appleframeworks', modules: 'CoreFoundation')
166 iokit = dependency('appleframeworks', modules: 'IOKit')
167 elif targetos == 'sunos'
168 socket = [cc.find_library('socket'),
169 cc.find_library('nsl'),
170 cc.find_library('resolv')]
171 elif targetos == 'haiku'
172 socket = [cc.find_library('posix_error_mapper'),
173 cc.find_library('network'),
174 cc.find_library('bsd')]
175 elif targetos == 'openbsd'
176 if not get_option('tcg').disabled() and target_dirs.length() > 0
177 # Disable OpenBSD W^X if available
178 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
183 if not get_option('kvm').disabled() and targetos == 'linux'
184 accelerators += 'CONFIG_KVM'
186 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
187 accelerators += 'CONFIG_XEN'
188 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
190 have_xen_pci_passthrough = false
192 if not get_option('whpx').disabled() and targetos == 'windows'
193 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
194 error('WHPX requires 64-bit host')
195 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
196 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
197 accelerators += 'CONFIG_WHPX'
200 if not get_option('hvf').disabled()
201 hvf = dependency('appleframeworks', modules: 'Hypervisor',
202 required: get_option('hvf'))
204 accelerators += 'CONFIG_HVF'
207 if not get_option('hax').disabled()
208 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
209 accelerators += 'CONFIG_HAX'
213 tcg_arch = config_host['ARCH']
214 if not get_option('tcg').disabled()
215 if cpu not in supported_cpus
216 if get_option('tcg_interpreter')
217 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
219 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
222 if get_option('tcg_interpreter')
224 elif config_host['ARCH'] == 'sparc64'
226 elif config_host['ARCH'] == 's390x'
228 elif config_host['ARCH'] in ['x86_64', 'x32']
230 elif config_host['ARCH'] == 'ppc64'
232 elif config_host['ARCH'] in ['riscv32', 'riscv64']
235 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
236 '-iquote', meson.current_source_dir() / 'accel/tcg',
237 language: ['c', 'cpp', 'objc'])
239 accelerators += 'CONFIG_TCG'
240 config_host += { 'CONFIG_TCG': 'y' }
243 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
244 error('KVM not available on this platform')
246 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
247 error('HVF not available on this platform')
249 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
250 error('WHPX not available on this platform')
252 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
253 if 'CONFIG_XEN' in accelerators
254 error('Xen PCI passthrough not available on this platform')
256 error('Xen PCI passthrough requested but Xen not enabled')
264 # The path to glib.h is added to all compilation commands. This was
265 # grandfathered in from the QEMU Makefiles.
266 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
267 native: false, language: ['c', 'cpp', 'objc'])
268 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
269 link_args: config_host['GLIB_LIBS'].split())
270 # override glib dep with the configure results (for subprojects)
271 meson.override_dependency('glib-2.0', glib)
274 if 'CONFIG_GIO' in config_host
275 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
276 link_args: config_host['GIO_LIBS'].split())
279 if 'CONFIG_TRACE_UST' in config_host
280 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
283 if 'CONFIG_TRACE_UST' in config_host
284 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
287 if 'CONFIG_GCRYPT' in config_host
288 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
289 link_args: config_host['GCRYPT_LIBS'].split())
292 if 'CONFIG_NETTLE' in config_host
293 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
294 link_args: config_host['NETTLE_LIBS'].split())
297 if 'CONFIG_GNUTLS' in config_host
298 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
299 link_args: config_host['GNUTLS_LIBS'].split())
302 if have_system or have_tools
303 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
304 method: 'pkg-config', static: enable_static)
307 if 'CONFIG_AUTH_PAM' in config_host
308 pam = cc.find_library('pam')
310 libaio = cc.find_library('aio', required: false)
311 zlib = dependency('zlib', required: true, static: enable_static)
312 linux_io_uring = not_found
313 if 'CONFIG_LINUX_IO_URING' in config_host
314 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
315 link_args: config_host['LINUX_IO_URING_LIBS'].split())
318 if 'CONFIG_LIBXML2' in config_host
319 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
320 link_args: config_host['LIBXML2_LIBS'].split())
323 if not get_option('libnfs').auto() or have_block
324 libnfs = dependency('libnfs', version: '>=1.9.3',
325 required: get_option('libnfs'),
326 method: 'pkg-config', static: enable_static)
331 #include <sys/types.h>
332 #ifdef CONFIG_LIBATTR
333 #include <attr/xattr.h>
335 #include <sys/xattr.h>
337 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
340 have_old_libattr = false
341 if not get_option('attr').disabled()
342 if cc.links(libattr_test)
343 libattr = declare_dependency()
345 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
346 required: get_option('attr'),
347 static: enable_static)
348 if libattr.found() and not \
349 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
351 if get_option('attr').enabled()
352 error('could not link libattr')
354 warning('could not link libattr, disabling')
357 have_old_libattr = libattr.found()
362 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
363 if cocoa.found() and get_option('sdl').enabled()
364 error('Cocoa and SDL cannot be enabled at the same time')
366 if cocoa.found() and get_option('gtk').enabled()
367 error('Cocoa and GTK+ cannot be enabled at the same time')
371 if not get_option('seccomp').auto() or have_system or have_tools
372 seccomp = dependency('libseccomp', version: '>=2.3.0',
373 required: get_option('seccomp'),
374 method: 'pkg-config', static: enable_static)
377 libcap_ng = not_found
378 if not get_option('cap_ng').auto() or have_system or have_tools
379 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
380 required: get_option('cap_ng'),
381 static: enable_static)
383 if libcap_ng.found() and not cc.links('''
387 capng_capability_to_name(CAPNG_EFFECTIVE);
389 }''', dependencies: libcap_ng)
390 libcap_ng = not_found
391 if get_option('cap_ng').enabled()
392 error('could not link libcap-ng')
394 warning('could not link libcap-ng, disabling')
398 if get_option('xkbcommon').auto() and not have_system and not have_tools
399 xkbcommon = not_found
401 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
402 method: 'pkg-config', static: enable_static)
405 if config_host.has_key('CONFIG_VDE')
406 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
409 if 'CONFIG_LIBPULSE' in config_host
410 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
411 link_args: config_host['PULSE_LIBS'].split())
414 if 'CONFIG_ALSA' in config_host
415 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
416 link_args: config_host['ALSA_LIBS'].split())
419 if 'CONFIG_LIBJACK' in config_host
420 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
423 spice_headers = not_found
424 if 'CONFIG_SPICE' in config_host
425 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
426 link_args: config_host['SPICE_LIBS'].split())
427 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
429 rt = cc.find_library('rt', required: false)
431 if 'CONFIG_PLUGIN' in config_host
432 libdl = cc.find_library('dl', required: true)
435 if not get_option('libiscsi').auto() or have_block
436 libiscsi = dependency('libiscsi', version: '>=1.9.0',
437 required: get_option('libiscsi'),
438 method: 'pkg-config', static: enable_static)
441 if not get_option('zstd').auto() or have_block
442 zstd = dependency('libzstd', version: '>=1.4.0',
443 required: get_option('zstd'),
444 method: 'pkg-config', static: enable_static)
447 if 'CONFIG_GBM' in config_host
448 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
449 link_args: config_host['GBM_LIBS'].split())
452 if 'CONFIG_VIRGL' in config_host
453 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
454 link_args: config_host['VIRGL_LIBS'].split())
457 if not get_option('curl').auto() or have_block
458 curl = dependency('libcurl', version: '>=7.29.0',
459 method: 'pkg-config',
460 required: get_option('curl'),
461 static: enable_static)
464 if targetos == 'linux' and (have_system or have_tools)
465 libudev = dependency('libudev',
466 method: 'pkg-config',
467 required: get_option('libudev'),
468 static: enable_static)
471 mpathlibs = [libudev]
472 mpathpersist = not_found
473 mpathpersist_new_api = false
474 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
475 mpath_test_source_new = '''
477 #include <mpath_persist.h>
478 unsigned mpath_mx_alloc_len = 1024;
480 static struct config *multipath_conf;
481 extern struct udev *udev;
482 extern struct config *get_multipath_config(void);
483 extern void put_multipath_config(struct config *conf);
485 struct config *get_multipath_config(void) { return multipath_conf; }
486 void put_multipath_config(struct config *conf) { }
489 multipath_conf = mpath_lib_init();
492 mpath_test_source_old = '''
494 #include <mpath_persist.h>
495 unsigned mpath_mx_alloc_len = 1024;
498 struct udev *udev = udev_new();
499 mpath_lib_init(udev);
502 libmpathpersist = cc.find_library('mpathpersist',
503 required: get_option('mpath'),
504 static: enable_static)
505 if libmpathpersist.found()
506 mpathlibs += libmpathpersist
508 mpathlibs += cc.find_library('devmapper',
509 required: get_option('mpath'),
510 static: enable_static)
512 mpathlibs += cc.find_library('multipath',
513 required: get_option('mpath'),
514 static: enable_static)
515 foreach lib: mpathlibs
521 if mpathlibs.length() == 0
522 msg = 'Dependencies missing for libmpathpersist'
523 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
524 mpathpersist = declare_dependency(dependencies: mpathlibs)
525 mpathpersist_new_api = true
526 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
527 mpathpersist = declare_dependency(dependencies: mpathlibs)
529 msg = 'Cannot detect libmpathpersist API'
531 if not mpathpersist.found()
532 if get_option('mpath').enabled()
535 warning(msg + ', disabling')
543 if have_system and not get_option('curses').disabled()
550 setlocale(LC_ALL, "");
552 addwstr(L"wide chars\n");
554 add_wch(WACS_DEGREE);
558 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
559 foreach curses_dep : curses_dep_list
560 if not curses.found()
561 curses = dependency(curses_dep,
563 method: 'pkg-config',
564 static: enable_static)
567 msg = get_option('curses').enabled() ? 'curses library not found' : ''
568 curses_compile_args = ['-DNCURSES_WIDECHAR']
570 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
571 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
573 msg = 'curses package not usable'
577 if not curses.found()
578 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
579 if targetos != 'windows' and not has_curses_h
580 message('Trying with /usr/include/ncursesw')
581 curses_compile_args += ['-I/usr/include/ncursesw']
582 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
585 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
586 foreach curses_libname : curses_libname_list
587 libcurses = cc.find_library(curses_libname,
589 static: enable_static)
591 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
592 curses = declare_dependency(compile_args: curses_compile_args,
593 dependencies: [libcurses])
596 msg = 'curses library not usable'
602 if not get_option('iconv').disabled()
603 foreach link_args : [ ['-liconv'], [] ]
604 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
605 # We need to use libiconv if available because mixing libiconv's headers with
606 # the system libc does not work.
607 # However, without adding glib to the dependencies -L/usr/local/lib will not be
608 # included in the command line and libiconv will not be found.
612 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
613 return conv != (iconv_t) -1;
614 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
615 iconv = declare_dependency(link_args: link_args, dependencies: glib)
620 if curses.found() and not iconv.found()
621 if get_option('iconv').enabled()
622 error('iconv not available')
624 msg = 'iconv required for curses UI but not available'
627 if not curses.found() and msg != ''
628 if get_option('curses').enabled()
631 warning(msg + ', disabling')
637 if not get_option('brlapi').auto() or have_system
638 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
639 required: get_option('brlapi'),
640 static: enable_static)
641 if brlapi.found() and not cc.links('''
644 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
646 if get_option('brlapi').enabled()
647 error('could not link brlapi')
649 warning('could not link brlapi, disabling')
655 if not get_option('sdl').auto() or (have_system and not cocoa.found())
656 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
657 sdl_image = not_found
660 # work around 2.0.8 bug
661 sdl = declare_dependency(compile_args: '-Wno-undef',
663 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
664 method: 'pkg-config', static: enable_static)
666 if get_option('sdl_image').enabled()
667 error('sdl-image required, but SDL was @0@'.format(
668 get_option('sdl').disabled() ? 'disabled' : 'not found'))
670 sdl_image = not_found
674 if not get_option('rbd').auto() or have_block
675 librados = cc.find_library('rados', required: get_option('rbd'),
676 static: enable_static)
677 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
678 required: get_option('rbd'),
679 static: enable_static)
680 if librados.found() and librbd.found() and cc.links('''
682 #include <rbd/librbd.h>
685 rados_create(&cluster, NULL);
687 }''', dependencies: [librbd, librados])
688 rbd = declare_dependency(dependencies: [librbd, librados])
692 glusterfs = not_found
693 glusterfs_ftruncate_has_stat = false
694 glusterfs_iocb_has_stat = false
695 if not get_option('glusterfs').auto() or have_block
696 glusterfs = dependency('glusterfs-api', version: '>=3',
697 required: get_option('glusterfs'),
698 method: 'pkg-config', static: enable_static)
700 glusterfs_ftruncate_has_stat = cc.links('''
701 #include <glusterfs/api/glfs.h>
706 /* new glfs_ftruncate() passes two additional args */
707 return glfs_ftruncate(NULL, 0, NULL, NULL);
709 ''', dependencies: glusterfs)
710 glusterfs_iocb_has_stat = cc.links('''
711 #include <glusterfs/api/glfs.h>
713 /* new glfs_io_cbk() passes two additional glfs_stat structs */
715 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
721 glfs_io_cbk iocb = &glusterfs_iocb;
722 iocb(NULL, 0 , NULL, NULL, NULL);
725 ''', dependencies: glusterfs)
729 if 'CONFIG_LIBSSH' in config_host
730 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
731 link_args: config_host['LIBSSH_LIBS'].split())
734 if not get_option('bzip2').auto() or have_block
735 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
736 required: get_option('bzip2'),
737 static: enable_static)
738 if libbzip2.found() and not cc.links('''
740 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
742 if get_option('bzip2').enabled()
743 error('could not link libbzip2')
745 warning('could not link libbzip2, disabling')
751 if not get_option('lzfse').auto() or have_block
752 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
753 required: get_option('lzfse'),
754 static: enable_static)
756 if liblzfse.found() and not cc.links('''
758 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
760 if get_option('lzfse').enabled()
761 error('could not link liblzfse')
763 warning('could not link liblzfse, disabling')
768 if 'CONFIG_AUDIO_OSS' in config_host
769 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
772 if 'CONFIG_AUDIO_DSOUND' in config_host
773 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
775 coreaudio = not_found
776 if 'CONFIG_AUDIO_COREAUDIO' in config_host
777 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
780 if 'CONFIG_OPENGL' in config_host
781 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
782 link_args: config_host['OPENGL_LIBS'].split())
787 if not get_option('gtk').auto() or (have_system and not cocoa.found())
788 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
789 method: 'pkg-config',
790 required: get_option('gtk'),
791 static: enable_static)
793 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
794 method: 'pkg-config',
796 static: enable_static)
797 gtk = declare_dependency(dependencies: [gtk, gtkx11])
802 if 'CONFIG_VTE' in config_host
803 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
804 link_args: config_host['VTE_LIBS'].split())
807 if gtkx11.found() or 'lm32-softmmu' in target_dirs
808 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
809 static: enable_static)
815 if get_option('vnc').enabled()
816 vnc = declare_dependency() # dummy dependency
817 png = dependency('libpng', required: get_option('vnc_png'),
818 method: 'pkg-config', static: enable_static)
819 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
820 method: 'pkg-config', static: enable_static)
821 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
822 required: get_option('vnc_sasl'),
823 static: enable_static)
825 sasl = declare_dependency(dependencies: sasl,
826 compile_args: '-DSTRUCT_IOVEC_DEFINED')
831 if not get_option('snappy').auto() or have_system
832 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
833 required: get_option('snappy'),
834 static: enable_static)
836 if snappy.found() and not cc.links('''
837 #include <snappy-c.h>
838 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
840 if get_option('snappy').enabled()
841 error('could not link libsnappy')
843 warning('could not link libsnappy, disabling')
848 if not get_option('lzo').auto() or have_system
849 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
850 required: get_option('lzo'),
851 static: enable_static)
853 if lzo.found() and not cc.links('''
854 #include <lzo/lzo1x.h>
855 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
857 if get_option('lzo').enabled()
858 error('could not link liblzo2')
860 warning('could not link liblzo2, disabling')
865 if 'CONFIG_RDMA' in config_host
866 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
869 if 'CONFIG_NUMA' in config_host
870 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
873 if 'CONFIG_XEN_BACKEND' in config_host
874 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
875 link_args: config_host['XEN_LIBS'].split())
878 if 'CONFIG_SMARTCARD' in config_host
879 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
880 link_args: config_host['SMARTCARD_LIBS'].split())
884 u2f = dependency('u2f-emu', required: get_option('u2f'),
885 method: 'pkg-config',
886 static: enable_static)
889 if 'CONFIG_USB_REDIR' in config_host
890 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
891 link_args: config_host['USB_REDIR_LIBS'].split())
894 if 'CONFIG_USB_LIBUSB' in config_host
895 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
896 link_args: config_host['LIBUSB_LIBS'].split())
899 if 'CONFIG_LIBPMEM' in config_host
900 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
901 link_args: config_host['LIBPMEM_LIBS'].split())
903 libdaxctl = not_found
904 if 'CONFIG_LIBDAXCTL' in config_host
905 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
908 if 'CONFIG_TASN1' in config_host
909 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
910 link_args: config_host['TASN1_LIBS'].split())
912 keyutils = dependency('libkeyutils', required: false,
913 method: 'pkg-config', static: enable_static)
915 has_gettid = cc.has_function('gettid')
920 if get_option('malloc') == 'system'
922 not get_option('malloc_trim').disabled() and \
923 cc.links('''#include <malloc.h>
924 int main(void) { malloc_trim(0); return 0; }''')
926 has_malloc_trim = false
927 malloc = cc.find_library(get_option('malloc'), required: true)
929 if not has_malloc_trim and get_option('malloc_trim').enabled()
930 if get_option('malloc') == 'system'
931 error('malloc_trim not available on this platform.')
933 error('malloc_trim not available with non-libc memory allocator')
937 # Check whether the glibc provides statx()
943 #include <sys/stat.h>
945 struct statx statxbuf;
946 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
950 has_statx = cc.links(statx_test)
952 have_vhost_user_blk_server = (targetos == 'linux' and
953 'CONFIG_VHOST_USER' in config_host)
955 if get_option('vhost_user_blk_server').enabled()
956 if targetos != 'linux'
957 error('vhost_user_blk_server requires linux')
958 elif 'CONFIG_VHOST_USER' not in config_host
959 error('vhost_user_blk_server requires vhost-user support')
961 elif get_option('vhost_user_blk_server').disabled() or not have_system
962 have_vhost_user_blk_server = false
966 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
967 error('Cannot enable fuse-lseek while fuse is disabled')
970 fuse = dependency('fuse3', required: get_option('fuse'),
971 version: '>=3.1', method: 'pkg-config',
972 static: enable_static)
974 fuse_lseek = not_found
975 if not get_option('fuse_lseek').disabled()
976 if fuse.version().version_compare('>=3.8')
978 fuse_lseek = declare_dependency()
979 elif get_option('fuse_lseek').enabled()
981 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
983 error('fuse-lseek requires libfuse, which was not found')
990 # Check for dependency on LTO
991 if not get_option('b_lto')
992 error('Selected Control-Flow Integrity but LTO is disabled')
994 if config_host.has_key('CONFIG_MODULES')
995 error('Selected Control-Flow Integrity is not compatible with modules')
997 # Check for cfi flags. CFI requires LTO so we can't use
998 # get_supported_arguments, but need a more complex "compiles" which allows
1000 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1001 args: ['-flto', '-fsanitize=cfi-icall'] )
1002 cfi_flags += '-fsanitize=cfi-icall'
1004 error('-fsanitize=cfi-icall is not supported by the compiler')
1006 if cc.compiles('int main () { return 0; }',
1007 name: '-fsanitize-cfi-icall-generalize-pointers',
1008 args: ['-flto', '-fsanitize=cfi-icall',
1009 '-fsanitize-cfi-icall-generalize-pointers'] )
1010 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1012 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1014 if get_option('cfi_debug')
1015 if cc.compiles('int main () { return 0; }',
1016 name: '-fno-sanitize-trap=cfi-icall',
1017 args: ['-flto', '-fsanitize=cfi-icall',
1018 '-fno-sanitize-trap=cfi-icall'] )
1019 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1021 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1024 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1025 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1032 have_virtfs = (targetos == 'linux' and
1037 if get_option('virtfs').enabled()
1039 if targetos != 'linux'
1040 error('virtio-9p (virtfs) requires Linux')
1041 elif not libcap_ng.found() or not libattr.found()
1042 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1043 elif not have_system
1044 error('virtio-9p (virtfs) needs system emulation support')
1047 elif get_option('virtfs').disabled()
1051 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1052 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1053 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1054 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1055 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1056 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1057 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1058 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1059 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1060 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1061 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1062 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1064 config_host_data.set('CONFIG_ATTR', libattr.found())
1065 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1066 config_host_data.set('CONFIG_COCOA', cocoa.found())
1067 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1068 config_host_data.set('CONFIG_LZO', lzo.found())
1069 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1070 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1071 config_host_data.set('CONFIG_CURL', curl.found())
1072 config_host_data.set('CONFIG_CURSES', curses.found())
1073 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1074 if glusterfs.found()
1075 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1076 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1077 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1078 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1079 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1080 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1082 config_host_data.set('CONFIG_GTK', gtk.found())
1083 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1084 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1085 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1086 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1087 config_host_data.set('CONFIG_RBD', rbd.found())
1088 config_host_data.set('CONFIG_SDL', sdl.found())
1089 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1090 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1091 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1092 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1093 config_host_data.set('CONFIG_VNC', vnc.found())
1094 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1095 config_host_data.set('CONFIG_VNC_PNG', png.found())
1096 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1097 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1098 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1099 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1100 config_host_data.set('CONFIG_GETTID', has_gettid)
1101 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1102 config_host_data.set('CONFIG_STATX', has_statx)
1103 config_host_data.set('CONFIG_ZSTD', zstd.found())
1104 config_host_data.set('CONFIG_FUSE', fuse.found())
1105 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1106 config_host_data.set('CONFIG_X11', x11.found())
1107 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1108 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1109 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1110 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1111 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1113 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1114 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1115 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1116 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1117 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1119 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1120 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1121 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1122 foreach k, v: config_host
1123 if ignored.contains(k)
1125 elif arrays.contains(k)
1127 v = '"' + '", "'.join(v.split()) + '", '
1129 config_host_data.set(k, v)
1131 config_host_data.set('HOST_' + v.to_upper(), 1)
1132 elif strings.contains(k)
1133 if not k.startswith('CONFIG_')
1134 k = 'CONFIG_' + k.to_upper()
1136 config_host_data.set_quoted(k, v)
1137 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1138 config_host_data.set(k, v == 'y' ? 1 : v)
1142 ########################
1143 # Target configuration #
1144 ########################
1146 minikconf = find_program('scripts/minikconf.py')
1148 config_all_devices = {}
1149 config_all_disas = {}
1150 config_devices_mak_list = []
1151 config_devices_h = {}
1152 config_target_h = {}
1153 config_target_mak = {}
1156 'alpha' : ['CONFIG_ALPHA_DIS'],
1157 'arm' : ['CONFIG_ARM_DIS'],
1158 'avr' : ['CONFIG_AVR_DIS'],
1159 'cris' : ['CONFIG_CRIS_DIS'],
1160 'hppa' : ['CONFIG_HPPA_DIS'],
1161 'i386' : ['CONFIG_I386_DIS'],
1162 'x86_64' : ['CONFIG_I386_DIS'],
1163 'x32' : ['CONFIG_I386_DIS'],
1164 'lm32' : ['CONFIG_LM32_DIS'],
1165 'm68k' : ['CONFIG_M68K_DIS'],
1166 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1167 'mips' : ['CONFIG_MIPS_DIS'],
1168 'moxie' : ['CONFIG_MOXIE_DIS'],
1169 'nios2' : ['CONFIG_NIOS2_DIS'],
1170 'or1k' : ['CONFIG_OPENRISC_DIS'],
1171 'ppc' : ['CONFIG_PPC_DIS'],
1172 'riscv' : ['CONFIG_RISCV_DIS'],
1173 'rx' : ['CONFIG_RX_DIS'],
1174 's390' : ['CONFIG_S390_DIS'],
1175 'sh4' : ['CONFIG_SH4_DIS'],
1176 'sparc' : ['CONFIG_SPARC_DIS'],
1177 'xtensa' : ['CONFIG_XTENSA_DIS'],
1179 if link_language == 'cpp'
1181 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1182 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1183 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1188 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1189 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1190 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1191 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1192 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1193 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1194 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1195 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1196 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1197 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1198 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1200 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1202 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1203 actual_target_dirs = []
1205 foreach target : target_dirs
1206 config_target = { 'TARGET_NAME': target.split('-')[0] }
1207 if target.endswith('linux-user')
1208 if targetos != 'linux'
1212 error('Target @0@ is only available on a Linux host'.format(target))
1214 config_target += { 'CONFIG_LINUX_USER': 'y' }
1215 elif target.endswith('bsd-user')
1216 if 'CONFIG_BSD' not in config_host
1220 error('Target @0@ is only available on a BSD host'.format(target))
1222 config_target += { 'CONFIG_BSD_USER': 'y' }
1223 elif target.endswith('softmmu')
1224 config_target += { 'CONFIG_SOFTMMU': 'y' }
1226 if target.endswith('-user')
1228 'CONFIG_USER_ONLY': 'y',
1229 'CONFIG_QEMU_INTERP_PREFIX':
1230 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1235 foreach sym: accelerators
1236 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1237 config_target += { sym: 'y' }
1238 config_all += { sym: 'y' }
1239 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1240 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1241 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1242 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1244 accel_kconfig += [ sym + '=y' ]
1247 if accel_kconfig.length() == 0
1251 error('No accelerator available for target @0@'.format(target))
1254 actual_target_dirs += target
1255 config_target += keyval.load('default-configs/targets' / target + '.mak')
1256 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1258 if 'TARGET_NEED_FDT' in config_target
1259 fdt_required += target
1263 if 'TARGET_BASE_ARCH' not in config_target
1264 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1266 if 'TARGET_ABI_DIR' not in config_target
1267 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1270 foreach k, v: disassemblers
1271 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1273 config_target += { sym: 'y' }
1274 config_all_disas += { sym: 'y' }
1279 config_target_data = configuration_data()
1280 foreach k, v: config_target
1281 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1283 elif ignored.contains(k)
1285 elif k == 'TARGET_BASE_ARCH'
1286 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1287 # not used to select files from sourcesets.
1288 config_target_data.set('TARGET_' + v.to_upper(), 1)
1289 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1290 config_target_data.set_quoted(k, v)
1292 config_target_data.set(k, 1)
1294 config_target_data.set(k, v)
1297 config_target_h += {target: configure_file(output: target + '-config-target.h',
1298 configuration: config_target_data)}
1300 if target.endswith('-softmmu')
1301 config_devices_mak = target + '-config-devices.mak'
1302 config_devices_mak = configure_file(
1303 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1304 output: config_devices_mak,
1305 depfile: config_devices_mak + '.d',
1307 command: [minikconf,
1308 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1309 config_devices_mak, '@DEPFILE@', '@INPUT@',
1310 host_kconfig, accel_kconfig])
1312 config_devices_data = configuration_data()
1313 config_devices = keyval.load(config_devices_mak)
1314 foreach k, v: config_devices
1315 config_devices_data.set(k, 1)
1317 config_devices_mak_list += config_devices_mak
1318 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1319 configuration: config_devices_data)}
1320 config_target += config_devices
1321 config_all_devices += config_devices
1323 config_target_mak += {target: config_target}
1325 target_dirs = actual_target_dirs
1327 # This configuration is used to build files that are shared by
1328 # multiple binaries, and then extracted out of the "common"
1329 # static_library target.
1331 # We do not use all_sources()/all_dependencies(), because it would
1332 # build literally all source files, including devices only used by
1333 # targets that are not built for this compilation. The CONFIG_ALL
1334 # pseudo symbol replaces it.
1336 config_all += config_all_devices
1337 config_all += config_host
1338 config_all += config_all_disas
1340 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1341 'CONFIG_SOFTMMU': have_system,
1342 'CONFIG_USER_ONLY': have_user,
1350 capstone = not_found
1351 capstone_opt = get_option('capstone')
1352 if capstone_opt in ['enabled', 'auto', 'system']
1353 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1354 capstone = dependency('capstone', version: '>=4.0',
1355 static: enable_static, method: 'pkg-config',
1356 required: capstone_opt == 'system' or
1357 capstone_opt == 'enabled' and not have_internal)
1359 capstone_opt = 'system'
1361 capstone_opt = 'internal'
1363 capstone_opt = 'disabled'
1366 if capstone_opt == 'internal'
1367 capstone_data = configuration_data()
1368 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1370 capstone_files = files(
1372 'capstone/MCInst.c',
1373 'capstone/MCInstrDesc.c',
1374 'capstone/MCRegisterInfo.c',
1375 'capstone/SStream.c',
1379 if 'CONFIG_ARM_DIS' in config_all_disas
1380 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1381 capstone_files += files(
1382 'capstone/arch/ARM/ARMDisassembler.c',
1383 'capstone/arch/ARM/ARMInstPrinter.c',
1384 'capstone/arch/ARM/ARMMapping.c',
1385 'capstone/arch/ARM/ARMModule.c'
1389 # FIXME: This config entry currently depends on a c++ compiler.
1390 # Which is needed for building libvixl, but not for capstone.
1391 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1392 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1393 capstone_files += files(
1394 'capstone/arch/AArch64/AArch64BaseInfo.c',
1395 'capstone/arch/AArch64/AArch64Disassembler.c',
1396 'capstone/arch/AArch64/AArch64InstPrinter.c',
1397 'capstone/arch/AArch64/AArch64Mapping.c',
1398 'capstone/arch/AArch64/AArch64Module.c'
1402 if 'CONFIG_PPC_DIS' in config_all_disas
1403 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1404 capstone_files += files(
1405 'capstone/arch/PowerPC/PPCDisassembler.c',
1406 'capstone/arch/PowerPC/PPCInstPrinter.c',
1407 'capstone/arch/PowerPC/PPCMapping.c',
1408 'capstone/arch/PowerPC/PPCModule.c'
1412 if 'CONFIG_S390_DIS' in config_all_disas
1413 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1414 capstone_files += files(
1415 'capstone/arch/SystemZ/SystemZDisassembler.c',
1416 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1417 'capstone/arch/SystemZ/SystemZMapping.c',
1418 'capstone/arch/SystemZ/SystemZModule.c',
1419 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1423 if 'CONFIG_I386_DIS' in config_all_disas
1424 capstone_data.set('CAPSTONE_HAS_X86', 1)
1425 capstone_files += files(
1426 'capstone/arch/X86/X86Disassembler.c',
1427 'capstone/arch/X86/X86DisassemblerDecoder.c',
1428 'capstone/arch/X86/X86ATTInstPrinter.c',
1429 'capstone/arch/X86/X86IntelInstPrinter.c',
1430 'capstone/arch/X86/X86InstPrinterCommon.c',
1431 'capstone/arch/X86/X86Mapping.c',
1432 'capstone/arch/X86/X86Module.c'
1436 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1439 # FIXME: There does not seem to be a way to completely replace the c_args
1440 # that come from add_project_arguments() -- we can only add to them.
1441 # So: disable all warnings with a big hammer.
1444 # Include all configuration defines via a header file, which will wind up
1445 # as a dependency on the object file, and thus changes here will result
1447 '-include', 'capstone-defs.h'
1450 libcapstone = static_library('capstone',
1451 sources: capstone_files,
1452 c_args: capstone_cargs,
1453 include_directories: 'capstone/include')
1454 capstone = declare_dependency(link_with: libcapstone,
1455 include_directories: 'capstone/include/capstone')
1459 slirp_opt = 'disabled'
1461 slirp_opt = get_option('slirp')
1462 if slirp_opt in ['enabled', 'auto', 'system']
1463 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1464 slirp = dependency('slirp', static: enable_static,
1465 method: 'pkg-config',
1466 required: slirp_opt == 'system' or
1467 slirp_opt == 'enabled' and not have_internal)
1469 slirp_opt = 'system'
1471 slirp_opt = 'internal'
1473 slirp_opt = 'disabled'
1476 if slirp_opt == 'internal'
1478 if targetos == 'windows'
1479 slirp_deps = cc.find_library('iphlpapi')
1481 slirp_conf = configuration_data()
1482 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1483 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1484 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1485 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1486 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1488 'slirp/src/arp_table.c',
1489 'slirp/src/bootp.c',
1490 'slirp/src/cksum.c',
1491 'slirp/src/dhcpv6.c',
1492 'slirp/src/dnssearch.c',
1494 'slirp/src/ip6_icmp.c',
1495 'slirp/src/ip6_input.c',
1496 'slirp/src/ip6_output.c',
1497 'slirp/src/ip_icmp.c',
1498 'slirp/src/ip_input.c',
1499 'slirp/src/ip_output.c',
1503 'slirp/src/ndp_table.c',
1505 'slirp/src/slirp.c',
1506 'slirp/src/socket.c',
1507 'slirp/src/state.c',
1508 'slirp/src/stream.c',
1509 'slirp/src/tcp_input.c',
1510 'slirp/src/tcp_output.c',
1511 'slirp/src/tcp_subr.c',
1512 'slirp/src/tcp_timer.c',
1517 'slirp/src/version.c',
1518 'slirp/src/vmstate.c',
1522 input : 'slirp/src/libslirp-version.h.in',
1523 output : 'libslirp-version.h',
1524 configuration: slirp_conf)
1526 slirp_inc = include_directories('slirp', 'slirp/src')
1527 libslirp = static_library('slirp',
1528 sources: slirp_files,
1529 c_args: slirp_cargs,
1530 include_directories: slirp_inc)
1531 slirp = declare_dependency(link_with: libslirp,
1532 dependencies: slirp_deps,
1533 include_directories: slirp_inc)
1538 fdt_opt = get_option('fdt')
1540 if fdt_opt in ['enabled', 'auto', 'system']
1541 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1542 fdt = cc.find_library('fdt', static: enable_static,
1543 required: fdt_opt == 'system' or
1544 fdt_opt == 'enabled' and not have_internal)
1545 if fdt.found() and cc.links('''
1547 #include <libfdt_env.h>
1548 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1552 fdt_opt = 'internal'
1554 fdt_opt = 'disabled'
1557 if fdt_opt == 'internal'
1560 'dtc/libfdt/fdt_ro.c',
1561 'dtc/libfdt/fdt_wip.c',
1562 'dtc/libfdt/fdt_sw.c',
1563 'dtc/libfdt/fdt_rw.c',
1564 'dtc/libfdt/fdt_strerror.c',
1565 'dtc/libfdt/fdt_empty_tree.c',
1566 'dtc/libfdt/fdt_addresses.c',
1567 'dtc/libfdt/fdt_overlay.c',
1568 'dtc/libfdt/fdt_check.c',
1571 fdt_inc = include_directories('dtc/libfdt')
1572 libfdt = static_library('fdt',
1574 include_directories: fdt_inc)
1575 fdt = declare_dependency(link_with: libfdt,
1576 include_directories: fdt_inc)
1579 if not fdt.found() and fdt_required.length() > 0
1580 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1583 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1584 config_host_data.set('CONFIG_FDT', fdt.found())
1585 config_host_data.set('CONFIG_SLIRP', slirp.found())
1587 #####################
1588 # Generated sources #
1589 #####################
1591 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1593 hxtool = find_program('scripts/hxtool')
1594 shaderinclude = find_program('scripts/shaderinclude.pl')
1595 qapi_gen = find_program('scripts/qapi-gen.py')
1596 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1597 meson.source_root() / 'scripts/qapi/commands.py',
1598 meson.source_root() / 'scripts/qapi/common.py',
1599 meson.source_root() / 'scripts/qapi/error.py',
1600 meson.source_root() / 'scripts/qapi/events.py',
1601 meson.source_root() / 'scripts/qapi/expr.py',
1602 meson.source_root() / 'scripts/qapi/gen.py',
1603 meson.source_root() / 'scripts/qapi/introspect.py',
1604 meson.source_root() / 'scripts/qapi/parser.py',
1605 meson.source_root() / 'scripts/qapi/schema.py',
1606 meson.source_root() / 'scripts/qapi/source.py',
1607 meson.source_root() / 'scripts/qapi/types.py',
1608 meson.source_root() / 'scripts/qapi/visit.py',
1609 meson.source_root() / 'scripts/qapi/common.py',
1610 meson.source_root() / 'scripts/qapi-gen.py'
1614 python, files('scripts/tracetool.py'),
1615 '--backend=' + config_host['TRACE_BACKENDS']
1618 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1619 meson.current_source_dir(),
1620 config_host['PKGVERSION'], meson.project_version()]
1621 qemu_version = custom_target('qemu-version.h',
1622 output: 'qemu-version.h',
1623 command: qemu_version_cmd,
1625 build_by_default: true,
1626 build_always_stale: true)
1627 genh += qemu_version
1631 ['qemu-options.hx', 'qemu-options.def'],
1632 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1636 ['hmp-commands.hx', 'hmp-commands.h'],
1637 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1640 foreach d : hx_headers
1641 hxdep += custom_target(d[1],
1645 build_by_default: true, # to be removed when added to a target
1646 command: [hxtool, '-h', '@INPUT0@'])
1654 authz_ss = ss.source_set()
1655 blockdev_ss = ss.source_set()
1656 block_ss = ss.source_set()
1657 bsd_user_ss = ss.source_set()
1658 chardev_ss = ss.source_set()
1659 common_ss = ss.source_set()
1660 crypto_ss = ss.source_set()
1661 io_ss = ss.source_set()
1662 linux_user_ss = ss.source_set()
1663 qmp_ss = ss.source_set()
1664 qom_ss = ss.source_set()
1665 softmmu_ss = ss.source_set()
1666 specific_fuzz_ss = ss.source_set()
1667 specific_ss = ss.source_set()
1668 stub_ss = ss.source_set()
1669 trace_ss = ss.source_set()
1670 user_ss = ss.source_set()
1671 util_ss = ss.source_set()
1676 target_softmmu_arch = {}
1682 # TODO: add each directory to the subdirs from its own meson.build, once
1684 trace_events_subdirs = [
1691 trace_events_subdirs += [ 'linux-user' ]
1694 trace_events_subdirs += [
1703 trace_events_subdirs += [
1715 'hw/block/dataplane',
1761 trace_events_subdirs += [
1777 vhost_user = not_found
1778 if 'CONFIG_VHOST_USER' in config_host
1779 libvhost_user = subproject('libvhost-user')
1780 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1795 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1796 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1799 stub_ss = stub_ss.apply(config_all, strict: false)
1801 util_ss.add_all(trace_ss)
1802 util_ss = util_ss.apply(config_all, strict: false)
1803 libqemuutil = static_library('qemuutil',
1804 sources: util_ss.sources() + stub_ss.sources() + genh,
1805 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1806 qemuutil = declare_dependency(link_with: libqemuutil,
1807 sources: genh + version_res)
1809 decodetree = generator(find_program('scripts/decodetree.py'),
1810 output: 'decode-@BASENAME@.c.inc',
1811 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1817 subdir('libdecnumber')
1827 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1833 blockdev_ss.add(files(
1840 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1841 # os-win32.c does not
1842 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1843 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1845 common_ss.add(files('cpus-common.c'))
1849 common_ss.add(capstone)
1850 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1851 specific_ss.add(files('exec-vary.c'))
1852 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1856 'tcg/tcg-op-gvec.c',
1861 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1873 subdir('linux-user')
1875 bsd_user_ss.add(files('gdbstub.c'))
1876 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1878 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1879 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1881 # needed for fuzzing binaries
1882 subdir('tests/qtest/libqos')
1883 subdir('tests/qtest/fuzz')
1885 ########################
1886 # Library dependencies #
1887 ########################
1891 foreach d, list : modules
1892 foreach m, module_ss : list
1893 if enable_modules and targetos != 'windows'
1894 module_ss = module_ss.apply(config_all, strict: false)
1895 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1896 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1904 block_ss.add_all(module_ss)
1906 softmmu_ss.add_all(module_ss)
1912 nm = find_program('nm')
1913 undefsym = find_program('scripts/undefsym.py')
1914 block_syms = custom_target('block.syms', output: 'block.syms',
1915 input: [libqemuutil, block_mods],
1917 command: [undefsym, nm, '@INPUT@'])
1918 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1919 input: [libqemuutil, softmmu_mods],
1921 command: [undefsym, nm, '@INPUT@'])
1923 qom_ss = qom_ss.apply(config_host, strict: false)
1924 libqom = static_library('qom', qom_ss.sources() + genh,
1925 dependencies: [qom_ss.dependencies()],
1928 qom = declare_dependency(link_whole: libqom)
1930 authz_ss = authz_ss.apply(config_host, strict: false)
1931 libauthz = static_library('authz', authz_ss.sources() + genh,
1932 dependencies: [authz_ss.dependencies()],
1934 build_by_default: false)
1936 authz = declare_dependency(link_whole: libauthz,
1939 crypto_ss = crypto_ss.apply(config_host, strict: false)
1940 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1941 dependencies: [crypto_ss.dependencies()],
1943 build_by_default: false)
1945 crypto = declare_dependency(link_whole: libcrypto,
1946 dependencies: [authz, qom])
1948 io_ss = io_ss.apply(config_host, strict: false)
1949 libio = static_library('io', io_ss.sources() + genh,
1950 dependencies: [io_ss.dependencies()],
1951 link_with: libqemuutil,
1953 build_by_default: false)
1955 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1957 libmigration = static_library('migration', sources: migration_files + genh,
1959 build_by_default: false)
1960 migration = declare_dependency(link_with: libmigration,
1961 dependencies: [zlib, qom, io])
1962 softmmu_ss.add(migration)
1964 block_ss = block_ss.apply(config_host, strict: false)
1965 libblock = static_library('block', block_ss.sources() + genh,
1966 dependencies: block_ss.dependencies(),
1967 link_depends: block_syms,
1969 build_by_default: false)
1971 block = declare_dependency(link_whole: [libblock],
1972 link_args: '@block.syms',
1973 dependencies: [crypto, io])
1975 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1976 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1977 dependencies: blockdev_ss.dependencies(),
1979 build_by_default: false)
1981 blockdev = declare_dependency(link_whole: [libblockdev],
1982 dependencies: [block])
1984 qmp_ss = qmp_ss.apply(config_host, strict: false)
1985 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1986 dependencies: qmp_ss.dependencies(),
1988 build_by_default: false)
1990 qmp = declare_dependency(link_whole: [libqmp])
1992 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1994 dependencies: [gnutls],
1995 build_by_default: false)
1997 chardev = declare_dependency(link_whole: libchardev)
1999 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2001 build_by_default: false)
2002 hwcore = declare_dependency(link_whole: libhwcore)
2003 common_ss.add(hwcore)
2009 foreach m : block_mods + softmmu_mods
2010 shared_module(m.name(),
2014 install_dir: qemu_moddir)
2017 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2018 common_ss.add(qom, qemuutil)
2020 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2021 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2023 common_all = common_ss.apply(config_all, strict: false)
2024 common_all = static_library('common',
2025 build_by_default: false,
2026 sources: common_all.sources() + genh,
2027 dependencies: common_all.dependencies(),
2030 feature_to_c = find_program('scripts/feature_to_c.sh')
2033 foreach target : target_dirs
2034 config_target = config_target_mak[target]
2035 target_name = config_target['TARGET_NAME']
2036 arch = config_target['TARGET_BASE_ARCH']
2037 arch_srcs = [config_target_h[target]]
2039 c_args = ['-DNEED_CPU_H',
2040 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2041 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2042 link_args = emulator_link_args
2044 config_target += config_host
2045 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2046 if targetos == 'linux'
2047 target_inc += include_directories('linux-headers', is_system: true)
2049 if target.endswith('-softmmu')
2050 qemu_target_name = 'qemu-system-' + target_name
2051 target_type='system'
2052 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2053 arch_srcs += t.sources()
2054 arch_deps += t.dependencies()
2056 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2057 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2058 arch_srcs += hw.sources()
2059 arch_deps += hw.dependencies()
2061 arch_srcs += config_devices_h[target]
2062 link_args += ['@block.syms', '@qemu.syms']
2064 abi = config_target['TARGET_ABI_DIR']
2066 qemu_target_name = 'qemu-' + target_name
2067 if 'CONFIG_LINUX_USER' in config_target
2068 base_dir = 'linux-user'
2069 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2071 base_dir = 'bsd-user'
2072 target_inc += include_directories('bsd-user/freebsd')
2074 target_inc += include_directories(
2078 if 'CONFIG_LINUX_USER' in config_target
2079 dir = base_dir / abi
2080 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2081 if config_target.has_key('TARGET_SYSTBL_ABI')
2083 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2084 extra_args : config_target['TARGET_SYSTBL_ABI'])
2089 if 'TARGET_XML_FILES' in config_target
2090 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2091 output: target + '-gdbstub-xml.c',
2092 input: files(config_target['TARGET_XML_FILES'].split()),
2093 command: [feature_to_c, '@INPUT@'],
2095 arch_srcs += gdbstub_xml
2098 t = target_arch[arch].apply(config_target, strict: false)
2099 arch_srcs += t.sources()
2100 arch_deps += t.dependencies()
2102 target_common = common_ss.apply(config_target, strict: false)
2103 objects = common_all.extract_objects(target_common.sources())
2104 deps = target_common.dependencies()
2106 target_specific = specific_ss.apply(config_target, strict: false)
2107 arch_srcs += target_specific.sources()
2108 arch_deps += target_specific.dependencies()
2110 lib = static_library('qemu-' + target,
2111 sources: arch_srcs + genh,
2112 dependencies: arch_deps,
2114 include_directories: target_inc,
2116 build_by_default: false,
2119 if target.endswith('-softmmu')
2121 'name': 'qemu-system-' + target_name,
2123 'sources': files('softmmu/main.c'),
2126 if targetos == 'windows' and (sdl.found() or gtk.found())
2128 'name': 'qemu-system-' + target_name + 'w',
2130 'sources': files('softmmu/main.c'),
2134 if config_host.has_key('CONFIG_FUZZ')
2135 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2137 'name': 'qemu-fuzz-' + target_name,
2139 'sources': specific_fuzz.sources(),
2140 'dependencies': specific_fuzz.dependencies(),
2145 'name': 'qemu-' + target_name,
2152 emulators += {exe['name']:
2153 executable(exe['name'], exe['sources'],
2156 dependencies: arch_deps + deps + exe['dependencies'],
2157 objects: lib.extract_all_objects(recursive: true),
2158 link_language: link_language,
2159 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2160 link_args: link_args,
2161 gui_app: exe['gui'])
2164 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2166 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2167 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2168 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2169 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2171 custom_target(exe['name'] + stp['ext'],
2172 input: trace_events_all,
2173 output: exe['name'] + stp['ext'],
2174 install: stp['install'],
2175 install_dir: get_option('datadir') / 'systemtap/tapset',
2177 tracetool, '--group=all', '--format=' + stp['fmt'],
2178 '--binary=' + stp['bin'],
2179 '--target-name=' + target_name,
2180 '--target-type=' + target_type,
2181 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2182 '@INPUT@', '@OUTPUT@'
2189 # Other build targets
2191 if 'CONFIG_PLUGIN' in config_host
2192 install_headers('include/qemu/qemu-plugin.h')
2195 if 'CONFIG_GUEST_AGENT' in config_host
2199 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2200 # when we don't build tools or system
2201 if xkbcommon.found()
2202 # used for the update-keymaps target, so include rules even if !have_tools
2203 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2204 dependencies: [qemuutil, xkbcommon], install: have_tools)
2208 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2209 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2210 qemu_io = executable('qemu-io', files('qemu-io.c'),
2211 dependencies: [block, qemuutil], install: true)
2212 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2213 dependencies: [blockdev, qemuutil, gnutls], install: true)
2215 subdir('storage-daemon')
2216 subdir('contrib/rdmacm-mux')
2217 subdir('contrib/elf2dmp')
2219 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2220 dependencies: qemuutil,
2223 if 'CONFIG_VHOST_USER' in config_host
2224 subdir('contrib/vhost-user-blk')
2225 subdir('contrib/vhost-user-gpu')
2226 subdir('contrib/vhost-user-input')
2227 subdir('contrib/vhost-user-scsi')
2230 if targetos == 'linux'
2231 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2232 dependencies: [qemuutil, libcap_ng],
2234 install_dir: get_option('libexecdir'))
2236 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2237 dependencies: [authz, crypto, io, qom, qemuutil,
2238 libcap_ng, mpathpersist],
2242 if 'CONFIG_IVSHMEM' in config_host
2243 subdir('contrib/ivshmem-client')
2244 subdir('contrib/ivshmem-server')
2257 if host_machine.system() == 'windows'
2259 find_program('scripts/nsis.py'),
2261 get_option('prefix'),
2262 meson.current_source_dir(),
2265 '-DDISPLAYVERSION=' + meson.project_version(),
2268 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2271 nsis_cmd += '-DCONFIG_GTK=y'
2274 nsis = custom_target('nsis',
2275 output: 'qemu-setup-' + meson.project_version() + '.exe',
2276 input: files('qemu.nsi'),
2277 build_always_stale: true,
2278 command: nsis_cmd + ['@INPUT@'])
2279 alias_target('installer', nsis)
2282 #########################
2283 # Configuration summary #
2284 #########################
2287 summary_info += {'Install prefix': get_option('prefix')}
2288 summary_info += {'BIOS directory': qemu_datadir}
2289 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2290 summary_info += {'binary directory': get_option('bindir')}
2291 summary_info += {'library directory': get_option('libdir')}
2292 summary_info += {'module directory': qemu_moddir}
2293 summary_info += {'libexec directory': get_option('libexecdir')}
2294 summary_info += {'include directory': get_option('includedir')}
2295 summary_info += {'config directory': get_option('sysconfdir')}
2296 if targetos != 'windows'
2297 summary_info += {'local state directory': get_option('localstatedir')}
2298 summary_info += {'Manual directory': get_option('mandir')}
2300 summary_info += {'local state directory': 'queried at runtime'}
2302 summary_info += {'Doc directory': get_option('docdir')}
2303 summary_info += {'Build directory': meson.current_build_dir()}
2304 summary_info += {'Source path': meson.current_source_dir()}
2305 summary_info += {'GIT binary': config_host['GIT']}
2306 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2307 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2308 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2309 if link_language == 'cpp'
2310 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2312 summary_info += {'C++ compiler': false}
2314 if targetos == 'darwin'
2315 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2317 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2318 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2319 + ['-O' + get_option('optimization')]
2320 + (get_option('debug') ? ['-g'] : []))}
2321 if link_language == 'cpp'
2322 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2323 + ['-O' + get_option('optimization')]
2324 + (get_option('debug') ? ['-g'] : []))}
2326 link_args = get_option(link_language + '_link_args')
2327 if link_args.length() > 0
2328 summary_info += {'LDFLAGS': ' '.join(link_args)}
2330 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2331 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2332 summary_info += {'make': config_host['MAKE']}
2333 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2334 summary_info += {'sphinx-build': sphinx_build.found()}
2335 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2336 # TODO: add back version
2337 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2338 if slirp_opt != 'disabled'
2339 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2341 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2342 if config_host.has_key('CONFIG_MODULES')
2343 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2345 summary_info += {'host CPU': cpu}
2346 summary_info += {'host endianness': build_machine.endian()}
2347 summary_info += {'target list': ' '.join(target_dirs)}
2348 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2349 summary_info += {'sparse enabled': sparse.found()}
2350 summary_info += {'strip binaries': get_option('strip')}
2351 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2352 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2353 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2354 if targetos == 'darwin'
2355 summary_info += {'Cocoa support': cocoa.found()}
2357 # TODO: add back version
2358 summary_info += {'SDL support': sdl.found()}
2359 summary_info += {'SDL image support': sdl_image.found()}
2360 # TODO: add back version
2361 summary_info += {'GTK support': gtk.found()}
2362 summary_info += {'pixman': pixman.found()}
2363 # TODO: add back version
2364 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2365 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2366 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2367 # TODO: add back version
2368 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2369 if config_host.has_key('CONFIG_GCRYPT')
2370 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2371 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2373 # TODO: add back version
2374 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2375 if config_host.has_key('CONFIG_NETTLE')
2376 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2378 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2379 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2380 summary_info += {'iconv support': iconv.found()}
2381 summary_info += {'curses support': curses.found()}
2382 # TODO: add back version
2383 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2384 summary_info += {'curl support': curl.found()}
2385 summary_info += {'mingw32 support': targetos == 'windows'}
2386 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2387 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2388 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2389 summary_info += {'VirtFS support': have_virtfs}
2390 summary_info += {'build virtiofs daemon': have_virtiofsd}
2391 summary_info += {'Multipath support': mpathpersist.found()}
2392 summary_info += {'VNC support': vnc.found()}
2394 summary_info += {'VNC SASL support': sasl.found()}
2395 summary_info += {'VNC JPEG support': jpeg.found()}
2396 summary_info += {'VNC PNG support': png.found()}
2398 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2399 if config_host.has_key('CONFIG_XEN_BACKEND')
2400 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2402 summary_info += {'brlapi support': brlapi.found()}
2403 summary_info += {'Documentation': build_docs}
2404 summary_info += {'PIE': get_option('b_pie')}
2405 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2406 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2407 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2408 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2409 summary_info += {'ATTR/XATTR support': libattr.found()}
2410 summary_info += {'Install blobs': get_option('install_blobs')}
2411 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2412 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2413 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2414 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2415 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2416 if config_all.has_key('CONFIG_TCG')
2417 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2418 summary_info += {'TCG interpreter': tcg_arch == 'tci'}
2420 summary_info += {'malloc trim support': has_malloc_trim}
2421 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2422 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2423 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2424 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2425 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2426 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2427 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2428 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2429 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2430 summary_info += {'libcap-ng support': libcap_ng.found()}
2431 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2432 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2433 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2434 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2435 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2436 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2437 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2438 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2439 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2440 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2441 if config_host['TRACE_BACKENDS'].split().contains('simple')
2442 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2444 # TODO: add back protocol and server version
2445 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2446 summary_info += {'rbd support': rbd.found()}
2447 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2448 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2449 summary_info += {'U2F support': u2f.found()}
2450 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2451 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2452 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2453 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2454 summary_info += {'libiscsi support': libiscsi.found()}
2455 summary_info += {'libnfs support': libnfs.found()}
2456 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2457 if targetos == 'windows'
2458 if 'WIN_SDK' in config_host
2459 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2461 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2462 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2463 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2465 summary_info += {'seccomp support': seccomp.found()}
2466 summary_info += {'CFI support': get_option('cfi')}
2467 summary_info += {'CFI debug support': get_option('cfi_debug')}
2468 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2469 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2470 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2471 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2472 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2473 summary_info += {'GlusterFS support': glusterfs.found()}
2474 summary_info += {'gcov': get_option('b_coverage')}
2475 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2476 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2477 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2478 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2479 summary_info += {'lzo support': lzo.found()}
2480 summary_info += {'snappy support': snappy.found()}
2481 summary_info += {'bzip2 support': libbzip2.found()}
2482 summary_info += {'lzfse support': liblzfse.found()}
2483 summary_info += {'zstd support': zstd.found()}
2484 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2485 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2486 summary_info += {'memory allocator': get_option('malloc')}
2487 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2488 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2489 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2490 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2491 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2492 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2493 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2494 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2495 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2496 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2497 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2498 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2499 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2500 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2501 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2502 summary_info += {'libudev': libudev.found()}
2503 summary_info += {'default devices': get_option('default_devices')}
2504 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2505 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2506 if config_host.has_key('HAVE_GDB_BIN')
2507 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2509 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2510 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2511 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2512 summary_info += {'FUSE exports': fuse.found()}
2513 summary_info += {'FUSE lseek': fuse_lseek.found()}
2514 summary(summary_info, bool_yn: true)
2516 if not supported_cpus.contains(cpu)
2518 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2520 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2521 message('The QEMU project intends to remove support for this host CPU in')
2522 message('a future release if nobody volunteers to maintain it and to')
2523 message('provide a build host for our continuous integration setup.')
2524 message('configure has succeeded and you can continue to build, but')
2525 message('if you care about QEMU on this platform you should contact')
2526 message('us upstream at qemu-devel@nongnu.org.')
2529 if not supported_oses.contains(targetos)
2531 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2533 message('Host OS ' + targetos + 'support is not currently maintained.')
2534 message('The QEMU project intends to remove support for this host OS in')
2535 message('a future release if nobody volunteers to maintain it and to')
2536 message('provide a build host for our continuous integration setup.')
2537 message('configure has succeeded and you can continue to build, but')
2538 message('if you care about QEMU on this platform you should contact')
2539 message('us upstream at qemu-devel@nongnu.org.')