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_project_arguments(config_host['QEMU_CFLAGS'].split(),
104 native: false, language: ['c', 'objc'])
105 add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
106 native: false, language: 'cpp')
107 add_project_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 if 'CONFIG_TCG_INTERPRETER' in config_host
118 elif config_host['ARCH'] == 'sparc64'
120 elif config_host['ARCH'] == 's390x'
122 elif config_host['ARCH'] in ['x86_64', 'x32']
124 elif config_host['ARCH'] == 'ppc64'
126 elif config_host['ARCH'] in ['riscv32', 'riscv64']
129 tcg_arch = config_host['ARCH']
131 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
133 '-iquote', meson.current_source_dir(),
134 '-iquote', meson.current_source_dir() / 'accel/tcg',
135 '-iquote', meson.current_source_dir() / 'include',
136 '-iquote', meson.current_source_dir() / 'disas/libvixl',
137 language: ['c', 'cpp', 'objc'])
139 link_language = meson.get_external_property('link_language', 'cpp')
140 if link_language == 'cpp'
141 add_languages('cpp', required: true, native: false)
143 if host_machine.system() == 'darwin'
144 add_languages('objc', required: false, native: false)
147 sparse = find_program('cgcc', required: get_option('sparse'))
150 command: [find_program('scripts/check_sparse.py'),
151 'compile_commands.json', sparse.full_path(), '-Wbitwise',
152 '-Wno-transparent-union', '-Wno-old-initializer',
153 '-Wno-non-pointer-null'])
156 ###########################################
157 # Target-specific checks and dependencies #
158 ###########################################
160 if targetos != 'linux' and get_option('mpath').enabled()
161 error('Multipath is supported only on Linux')
164 m = cc.find_library('m', required: false)
165 util = cc.find_library('util', required: false)
171 emulator_link_args = []
174 if targetos == 'windows'
175 socket = cc.find_library('ws2_32')
176 winmm = cc.find_library('winmm')
178 win = import('windows')
179 version_res = win.compile_resources('version.rc',
180 depend_files: files('pc-bios/qemu-nsis.ico'),
181 include_directories: include_directories('.'))
182 elif targetos == 'darwin'
183 coref = dependency('appleframeworks', modules: 'CoreFoundation')
184 iokit = dependency('appleframeworks', modules: 'IOKit')
185 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
186 elif targetos == 'sunos'
187 socket = [cc.find_library('socket'),
188 cc.find_library('nsl'),
189 cc.find_library('resolv')]
190 elif targetos == 'haiku'
191 socket = [cc.find_library('posix_error_mapper'),
192 cc.find_library('network'),
193 cc.find_library('bsd')]
194 elif targetos == 'openbsd'
195 if not get_option('tcg').disabled() and target_dirs.length() > 0
196 # Disable OpenBSD W^X if available
197 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
202 if not get_option('kvm').disabled() and targetos == 'linux'
203 accelerators += 'CONFIG_KVM'
205 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
206 accelerators += 'CONFIG_XEN'
207 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
209 have_xen_pci_passthrough = false
211 if not get_option('whpx').disabled() and targetos == 'windows'
212 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
213 error('WHPX requires 64-bit host')
214 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
215 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
216 accelerators += 'CONFIG_WHPX'
219 if not get_option('hvf').disabled()
220 hvf = dependency('appleframeworks', modules: 'Hypervisor',
221 required: get_option('hvf'))
223 accelerators += 'CONFIG_HVF'
226 if not get_option('hax').disabled()
227 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
228 accelerators += 'CONFIG_HAX'
231 if not get_option('tcg').disabled()
232 if cpu not in supported_cpus
233 if 'CONFIG_TCG_INTERPRETER' in config_host
234 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
236 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
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')
259 if not cocoa.found() and get_option('cocoa').enabled()
260 error('Cocoa not available on this platform')
267 # The path to glib.h is added to all compilation commands. This was
268 # grandfathered in from the QEMU Makefiles.
269 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
270 native: false, language: ['c', 'cpp', 'objc'])
271 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
272 link_args: config_host['GLIB_LIBS'].split())
273 # override glib dep with the configure results (for subprojects)
274 meson.override_dependency('glib-2.0', glib)
277 if 'CONFIG_GIO' in config_host
278 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
279 link_args: config_host['GIO_LIBS'].split())
282 if 'CONFIG_TRACE_UST' in config_host
283 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
286 if 'CONFIG_TRACE_UST' in config_host
287 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
290 if 'CONFIG_GCRYPT' in config_host
291 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
292 link_args: config_host['GCRYPT_LIBS'].split())
295 if 'CONFIG_NETTLE' in config_host
296 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
297 link_args: config_host['NETTLE_LIBS'].split())
300 if 'CONFIG_GNUTLS' in config_host
301 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
302 link_args: config_host['GNUTLS_LIBS'].split())
305 if have_system or have_tools
306 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
307 method: 'pkg-config', static: enable_static)
310 if 'CONFIG_AUTH_PAM' in config_host
311 pam = cc.find_library('pam')
313 libaio = cc.find_library('aio', required: false)
314 zlib = dependency('zlib', required: true, static: enable_static)
315 linux_io_uring = not_found
316 if 'CONFIG_LINUX_IO_URING' in config_host
317 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
318 link_args: config_host['LINUX_IO_URING_LIBS'].split())
321 if 'CONFIG_LIBXML2' in config_host
322 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
323 link_args: config_host['LIBXML2_LIBS'].split())
326 if not get_option('libnfs').auto() or have_block
327 libnfs = dependency('libnfs', version: '>=1.9.3',
328 required: get_option('libnfs'),
329 method: 'pkg-config', static: enable_static)
334 #include <sys/types.h>
335 #ifdef CONFIG_LIBATTR
336 #include <attr/xattr.h>
338 #include <sys/xattr.h>
340 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
343 have_old_libattr = false
344 if not get_option('attr').disabled()
345 if cc.links(libattr_test)
346 libattr = declare_dependency()
348 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
349 required: get_option('attr'),
350 static: enable_static)
351 if libattr.found() and not \
352 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
354 if get_option('attr').enabled()
355 error('could not link libattr')
357 warning('could not link libattr, disabling')
360 have_old_libattr = libattr.found()
366 if not get_option('seccomp').auto() or have_system or have_tools
367 seccomp = dependency('libseccomp', version: '>=2.3.0',
368 required: get_option('seccomp'),
369 method: 'pkg-config', static: enable_static)
372 libcap_ng = not_found
373 if not get_option('cap_ng').auto() or have_system or have_tools
374 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
375 required: get_option('cap_ng'),
376 static: enable_static)
378 if libcap_ng.found() and not cc.links('''
382 capng_capability_to_name(CAPNG_EFFECTIVE);
384 }''', dependencies: libcap_ng)
385 libcap_ng = not_found
386 if get_option('cap_ng').enabled()
387 error('could not link libcap-ng')
389 warning('could not link libcap-ng, disabling')
393 if get_option('xkbcommon').auto() and not have_system and not have_tools
394 xkbcommon = not_found
396 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
397 method: 'pkg-config', static: enable_static)
400 if config_host.has_key('CONFIG_VDE')
401 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
404 if 'CONFIG_LIBPULSE' in config_host
405 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
406 link_args: config_host['PULSE_LIBS'].split())
409 if 'CONFIG_ALSA' in config_host
410 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
411 link_args: config_host['ALSA_LIBS'].split())
414 if 'CONFIG_LIBJACK' in config_host
415 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
418 spice_headers = not_found
419 if 'CONFIG_SPICE' in config_host
420 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
421 link_args: config_host['SPICE_LIBS'].split())
422 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
424 rt = cc.find_library('rt', required: false)
426 if 'CONFIG_PLUGIN' in config_host
427 libdl = cc.find_library('dl', required: true)
430 if not get_option('libiscsi').auto() or have_block
431 libiscsi = dependency('libiscsi', version: '>=1.9.0',
432 required: get_option('libiscsi'),
433 method: 'pkg-config', static: enable_static)
436 if not get_option('zstd').auto() or have_block
437 zstd = dependency('libzstd', version: '>=1.4.0',
438 required: get_option('zstd'),
439 method: 'pkg-config', static: enable_static)
442 if 'CONFIG_GBM' in config_host
443 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
444 link_args: config_host['GBM_LIBS'].split())
447 if 'CONFIG_VIRGL' in config_host
448 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
449 link_args: config_host['VIRGL_LIBS'].split())
452 if not get_option('curl').auto() or have_block
453 curl = dependency('libcurl', version: '>=7.29.0',
454 method: 'pkg-config',
455 required: get_option('curl'),
456 static: enable_static)
459 if targetos == 'linux' and (have_system or have_tools)
460 libudev = dependency('libudev',
461 method: 'pkg-config',
462 required: get_option('libudev'),
463 static: enable_static)
466 mpathlibs = [libudev]
467 mpathpersist = not_found
468 mpathpersist_new_api = false
469 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
470 mpath_test_source_new = '''
472 #include <mpath_persist.h>
473 unsigned mpath_mx_alloc_len = 1024;
475 static struct config *multipath_conf;
476 extern struct udev *udev;
477 extern struct config *get_multipath_config(void);
478 extern void put_multipath_config(struct config *conf);
480 struct config *get_multipath_config(void) { return multipath_conf; }
481 void put_multipath_config(struct config *conf) { }
484 multipath_conf = mpath_lib_init();
487 mpath_test_source_old = '''
489 #include <mpath_persist.h>
490 unsigned mpath_mx_alloc_len = 1024;
493 struct udev *udev = udev_new();
494 mpath_lib_init(udev);
497 libmpathpersist = cc.find_library('mpathpersist',
498 required: get_option('mpath'),
499 static: enable_static)
500 if libmpathpersist.found()
501 mpathlibs += libmpathpersist
503 mpathlibs += cc.find_library('devmapper',
504 required: get_option('mpath'),
505 static: enable_static)
507 mpathlibs += cc.find_library('multipath',
508 required: get_option('mpath'),
509 static: enable_static)
510 foreach lib: mpathlibs
516 if mpathlibs.length() == 0
517 msg = 'Dependencies missing for libmpathpersist'
518 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
519 mpathpersist = declare_dependency(dependencies: mpathlibs)
520 mpathpersist_new_api = true
521 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
522 mpathpersist = declare_dependency(dependencies: mpathlibs)
524 msg = 'Cannot detect libmpathpersist API'
526 if not mpathpersist.found()
527 if get_option('mpath').enabled()
530 warning(msg + ', disabling')
538 if have_system and not get_option('curses').disabled()
545 setlocale(LC_ALL, "");
547 addwstr(L"wide chars\n");
549 add_wch(WACS_DEGREE);
553 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
554 foreach curses_dep : curses_dep_list
555 if not curses.found()
556 curses = dependency(curses_dep,
558 method: 'pkg-config',
559 static: enable_static)
562 msg = get_option('curses').enabled() ? 'curses library not found' : ''
563 curses_compile_args = ['-DNCURSES_WIDECHAR']
565 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
566 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
568 msg = 'curses package not usable'
572 if not curses.found()
573 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
574 if targetos != 'windows' and not has_curses_h
575 message('Trying with /usr/include/ncursesw')
576 curses_compile_args += ['-I/usr/include/ncursesw']
577 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
580 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
581 foreach curses_libname : curses_libname_list
582 libcurses = cc.find_library(curses_libname,
584 static: enable_static)
586 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
587 curses = declare_dependency(compile_args: curses_compile_args,
588 dependencies: [libcurses])
591 msg = 'curses library not usable'
597 if not get_option('iconv').disabled()
598 foreach link_args : [ ['-liconv'], [] ]
599 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
600 # We need to use libiconv if available because mixing libiconv's headers with
601 # the system libc does not work.
602 # However, without adding glib to the dependencies -L/usr/local/lib will not be
603 # included in the command line and libiconv will not be found.
607 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
608 return conv != (iconv_t) -1;
609 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
610 iconv = declare_dependency(link_args: link_args, dependencies: glib)
615 if curses.found() and not iconv.found()
616 if get_option('iconv').enabled()
617 error('iconv not available')
619 msg = 'iconv required for curses UI but not available'
622 if not curses.found() and msg != ''
623 if get_option('curses').enabled()
626 warning(msg + ', disabling')
632 if not get_option('brlapi').auto() or have_system
633 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
634 required: get_option('brlapi'),
635 static: enable_static)
636 if brlapi.found() and not cc.links('''
639 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
641 if get_option('brlapi').enabled()
642 error('could not link brlapi')
644 warning('could not link brlapi, disabling')
651 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
652 sdl_image = not_found
655 # work around 2.0.8 bug
656 sdl = declare_dependency(compile_args: '-Wno-undef',
658 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
659 method: 'pkg-config', static: enable_static)
661 if get_option('sdl_image').enabled()
662 error('sdl-image required, but SDL was @0@'.format(
663 get_option('sdl').disabled() ? 'disabled' : 'not found'))
665 sdl_image = not_found
669 if not get_option('rbd').auto() or have_block
670 librados = cc.find_library('rados', required: get_option('rbd'),
671 static: enable_static)
672 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
673 required: get_option('rbd'),
674 static: enable_static)
675 if librados.found() and librbd.found() and cc.links('''
677 #include <rbd/librbd.h>
680 rados_create(&cluster, NULL);
682 }''', dependencies: [librbd, librados])
683 rbd = declare_dependency(dependencies: [librbd, librados])
687 glusterfs = not_found
688 glusterfs_ftruncate_has_stat = false
689 glusterfs_iocb_has_stat = false
690 if not get_option('glusterfs').auto() or have_block
691 glusterfs = dependency('glusterfs-api', version: '>=3',
692 required: get_option('glusterfs'),
693 method: 'pkg-config', static: enable_static)
695 glusterfs_ftruncate_has_stat = cc.links('''
696 #include <glusterfs/api/glfs.h>
701 /* new glfs_ftruncate() passes two additional args */
702 return glfs_ftruncate(NULL, 0, NULL, NULL);
704 ''', dependencies: glusterfs)
705 glusterfs_iocb_has_stat = cc.links('''
706 #include <glusterfs/api/glfs.h>
708 /* new glfs_io_cbk() passes two additional glfs_stat structs */
710 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
716 glfs_io_cbk iocb = &glusterfs_iocb;
717 iocb(NULL, 0 , NULL, NULL, NULL);
720 ''', dependencies: glusterfs)
724 if 'CONFIG_LIBSSH' in config_host
725 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
726 link_args: config_host['LIBSSH_LIBS'].split())
729 if not get_option('bzip2').auto() or have_block
730 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
731 required: get_option('bzip2'),
732 static: enable_static)
733 if libbzip2.found() and not cc.links('''
735 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
737 if get_option('bzip2').enabled()
738 error('could not link libbzip2')
740 warning('could not link libbzip2, disabling')
746 if not get_option('lzfse').auto() or have_block
747 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
748 required: get_option('lzfse'),
749 static: enable_static)
751 if liblzfse.found() and not cc.links('''
753 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
755 if get_option('lzfse').enabled()
756 error('could not link liblzfse')
758 warning('could not link liblzfse, disabling')
763 if 'CONFIG_AUDIO_OSS' in config_host
764 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
767 if 'CONFIG_AUDIO_DSOUND' in config_host
768 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
770 coreaudio = not_found
771 if 'CONFIG_AUDIO_COREAUDIO' in config_host
772 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
775 if 'CONFIG_OPENGL' in config_host
776 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
777 link_args: config_host['OPENGL_LIBS'].split())
780 if 'CONFIG_GTK' in config_host
781 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
782 link_args: config_host['GTK_LIBS'].split())
785 if 'CONFIG_VTE' in config_host
786 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
787 link_args: config_host['VTE_LIBS'].split())
790 if 'CONFIG_X11' in config_host
791 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
792 link_args: config_host['X11_LIBS'].split())
798 if get_option('vnc').enabled()
799 vnc = declare_dependency() # dummy dependency
800 png = dependency('libpng', required: get_option('vnc_png'),
801 method: 'pkg-config', static: enable_static)
802 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
803 method: 'pkg-config', static: enable_static)
804 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
805 required: get_option('vnc_sasl'),
806 static: enable_static)
808 sasl = declare_dependency(dependencies: sasl,
809 compile_args: '-DSTRUCT_IOVEC_DEFINED')
814 if not get_option('snappy').auto() or have_system
815 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
816 required: get_option('snappy'),
817 static: enable_static)
819 if snappy.found() and not cc.links('''
820 #include <snappy-c.h>
821 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
823 if get_option('snappy').enabled()
824 error('could not link libsnappy')
826 warning('could not link libsnappy, disabling')
831 if not get_option('lzo').auto() or have_system
832 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
833 required: get_option('lzo'),
834 static: enable_static)
836 if lzo.found() and not cc.links('''
837 #include <lzo/lzo1x.h>
838 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
840 if get_option('lzo').enabled()
841 error('could not link liblzo2')
843 warning('could not link liblzo2, disabling')
848 if 'CONFIG_RDMA' in config_host
849 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
852 if 'CONFIG_NUMA' in config_host
853 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
856 if 'CONFIG_XEN_BACKEND' in config_host
857 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
858 link_args: config_host['XEN_LIBS'].split())
861 if 'CONFIG_SMARTCARD' in config_host
862 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
863 link_args: config_host['SMARTCARD_LIBS'].split())
867 u2f = dependency('u2f-emu', required: get_option('u2f'),
868 method: 'pkg-config',
869 static: enable_static)
872 if 'CONFIG_USB_REDIR' in config_host
873 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
874 link_args: config_host['USB_REDIR_LIBS'].split())
877 if 'CONFIG_USB_LIBUSB' in config_host
878 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
879 link_args: config_host['LIBUSB_LIBS'].split())
882 if 'CONFIG_LIBPMEM' in config_host
883 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
884 link_args: config_host['LIBPMEM_LIBS'].split())
886 libdaxctl = not_found
887 if 'CONFIG_LIBDAXCTL' in config_host
888 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
891 if 'CONFIG_TASN1' in config_host
892 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
893 link_args: config_host['TASN1_LIBS'].split())
895 keyutils = dependency('libkeyutils', required: false,
896 method: 'pkg-config', static: enable_static)
898 has_gettid = cc.has_function('gettid')
903 if get_option('malloc') == 'system'
905 not get_option('malloc_trim').disabled() and \
906 cc.links('''#include <malloc.h>
907 int main(void) { malloc_trim(0); return 0; }''')
909 has_malloc_trim = false
910 malloc = cc.find_library(get_option('malloc'), required: true)
912 if not has_malloc_trim and get_option('malloc_trim').enabled()
913 if get_option('malloc') == 'system'
914 error('malloc_trim not available on this platform.')
916 error('malloc_trim not available with non-libc memory allocator')
920 # Check whether the glibc provides statx()
926 #include <sys/stat.h>
928 struct statx statxbuf;
929 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
933 has_statx = cc.links(statx_test)
935 have_vhost_user_blk_server = (targetos == 'linux' and
936 'CONFIG_VHOST_USER' in config_host)
938 if get_option('vhost_user_blk_server').enabled()
939 if targetos != 'linux'
940 error('vhost_user_blk_server requires linux')
941 elif 'CONFIG_VHOST_USER' not in config_host
942 error('vhost_user_blk_server requires vhost-user support')
944 elif get_option('vhost_user_blk_server').disabled() or not have_system
945 have_vhost_user_blk_server = false
949 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
950 error('Cannot enable fuse-lseek while fuse is disabled')
953 fuse = dependency('fuse3', required: get_option('fuse'),
954 version: '>=3.1', method: 'pkg-config',
955 static: enable_static)
957 fuse_lseek = not_found
958 if not get_option('fuse_lseek').disabled()
959 if fuse.version().version_compare('>=3.8')
961 fuse_lseek = declare_dependency()
962 elif get_option('fuse_lseek').enabled()
964 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
966 error('fuse-lseek requires libfuse, which was not found')
973 # Check for dependency on LTO
974 if not get_option('b_lto')
975 error('Selected Control-Flow Integrity but LTO is disabled')
977 if config_host.has_key('CONFIG_MODULES')
978 error('Selected Control-Flow Integrity is not compatible with modules')
980 # Check for cfi flags. CFI requires LTO so we can't use
981 # get_supported_arguments, but need a more complex "compiles" which allows
983 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
984 args: ['-flto', '-fsanitize=cfi-icall'] )
985 cfi_flags += '-fsanitize=cfi-icall'
987 error('-fsanitize=cfi-icall is not supported by the compiler')
989 if cc.compiles('int main () { return 0; }',
990 name: '-fsanitize-cfi-icall-generalize-pointers',
991 args: ['-flto', '-fsanitize=cfi-icall',
992 '-fsanitize-cfi-icall-generalize-pointers'] )
993 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
995 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
997 if get_option('cfi_debug')
998 if cc.compiles('int main () { return 0; }',
999 name: '-fno-sanitize-trap=cfi-icall',
1000 args: ['-flto', '-fsanitize=cfi-icall',
1001 '-fno-sanitize-trap=cfi-icall'] )
1002 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1004 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1007 add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1008 add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1015 have_virtfs = (targetos == 'linux' and
1020 if get_option('virtfs').enabled()
1022 if targetos != 'linux'
1023 error('virtio-9p (virtfs) requires Linux')
1024 elif not libcap_ng.found() or not libattr.found()
1025 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1026 elif not have_system
1027 error('virtio-9p (virtfs) needs system emulation support')
1030 elif get_option('virtfs').disabled()
1034 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1035 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1036 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1037 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1038 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1039 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1040 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1041 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1042 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1043 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1044 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1045 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1047 config_host_data.set('CONFIG_ATTR', libattr.found())
1048 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1049 config_host_data.set('CONFIG_COCOA', cocoa.found())
1050 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1051 config_host_data.set('CONFIG_LZO', lzo.found())
1052 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1053 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1054 config_host_data.set('CONFIG_CURL', curl.found())
1055 config_host_data.set('CONFIG_CURSES', curses.found())
1056 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1057 if glusterfs.found()
1058 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1059 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1060 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1061 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1062 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1063 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1065 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1066 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1067 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1068 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1069 config_host_data.set('CONFIG_RBD', rbd.found())
1070 config_host_data.set('CONFIG_SDL', sdl.found())
1071 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1072 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1073 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1074 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1075 config_host_data.set('CONFIG_VNC', vnc.found())
1076 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1077 config_host_data.set('CONFIG_VNC_PNG', png.found())
1078 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1079 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1080 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1081 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1082 config_host_data.set('CONFIG_GETTID', has_gettid)
1083 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1084 config_host_data.set('CONFIG_STATX', has_statx)
1085 config_host_data.set('CONFIG_ZSTD', zstd.found())
1086 config_host_data.set('CONFIG_FUSE', fuse.found())
1087 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1088 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1089 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1090 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1091 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1092 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1094 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1095 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1096 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1097 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1098 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1099 config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
1101 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1102 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1103 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1104 foreach k, v: config_host
1105 if ignored.contains(k)
1107 elif arrays.contains(k)
1109 v = '"' + '", "'.join(v.split()) + '", '
1111 config_host_data.set(k, v)
1113 config_host_data.set('HOST_' + v.to_upper(), 1)
1114 elif strings.contains(k)
1115 if not k.startswith('CONFIG_')
1116 k = 'CONFIG_' + k.to_upper()
1118 config_host_data.set_quoted(k, v)
1119 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1120 config_host_data.set(k, v == 'y' ? 1 : v)
1124 ########################
1125 # Target configuration #
1126 ########################
1128 minikconf = find_program('scripts/minikconf.py')
1130 config_all_devices = {}
1131 config_all_disas = {}
1132 config_devices_mak_list = []
1133 config_devices_h = {}
1134 config_target_h = {}
1135 config_target_mak = {}
1138 'alpha' : ['CONFIG_ALPHA_DIS'],
1139 'arm' : ['CONFIG_ARM_DIS'],
1140 'avr' : ['CONFIG_AVR_DIS'],
1141 'cris' : ['CONFIG_CRIS_DIS'],
1142 'hppa' : ['CONFIG_HPPA_DIS'],
1143 'i386' : ['CONFIG_I386_DIS'],
1144 'x86_64' : ['CONFIG_I386_DIS'],
1145 'x32' : ['CONFIG_I386_DIS'],
1146 'lm32' : ['CONFIG_LM32_DIS'],
1147 'm68k' : ['CONFIG_M68K_DIS'],
1148 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1149 'mips' : ['CONFIG_MIPS_DIS'],
1150 'moxie' : ['CONFIG_MOXIE_DIS'],
1151 'nios2' : ['CONFIG_NIOS2_DIS'],
1152 'or1k' : ['CONFIG_OPENRISC_DIS'],
1153 'ppc' : ['CONFIG_PPC_DIS'],
1154 'riscv' : ['CONFIG_RISCV_DIS'],
1155 'rx' : ['CONFIG_RX_DIS'],
1156 's390' : ['CONFIG_S390_DIS'],
1157 'sh4' : ['CONFIG_SH4_DIS'],
1158 'sparc' : ['CONFIG_SPARC_DIS'],
1159 'xtensa' : ['CONFIG_XTENSA_DIS'],
1161 if link_language == 'cpp'
1163 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1164 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1165 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1170 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1171 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1172 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1173 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1174 ('CONFIG_X11' in config_host ? ['CONFIG_X11=y'] : []) + \
1175 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1176 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1177 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1178 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1179 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1180 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1182 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1184 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1185 actual_target_dirs = []
1187 foreach target : target_dirs
1188 config_target = { 'TARGET_NAME': target.split('-')[0] }
1189 if target.endswith('linux-user')
1190 if targetos != 'linux'
1194 error('Target @0@ is only available on a Linux host'.format(target))
1196 config_target += { 'CONFIG_LINUX_USER': 'y' }
1197 elif target.endswith('bsd-user')
1198 if 'CONFIG_BSD' not in config_host
1202 error('Target @0@ is only available on a BSD host'.format(target))
1204 config_target += { 'CONFIG_BSD_USER': 'y' }
1205 elif target.endswith('softmmu')
1206 config_target += { 'CONFIG_SOFTMMU': 'y' }
1208 if target.endswith('-user')
1210 'CONFIG_USER_ONLY': 'y',
1211 'CONFIG_QEMU_INTERP_PREFIX':
1212 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1217 foreach sym: accelerators
1218 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1219 config_target += { sym: 'y' }
1220 config_all += { sym: 'y' }
1221 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1222 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1224 accel_kconfig += [ sym + '=y' ]
1227 if accel_kconfig.length() == 0
1231 error('No accelerator available for target @0@'.format(target))
1234 actual_target_dirs += target
1235 config_target += keyval.load('default-configs/targets' / target + '.mak')
1236 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1238 if 'TARGET_NEED_FDT' in config_target
1239 fdt_required += target
1243 if 'TARGET_BASE_ARCH' not in config_target
1244 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1246 if 'TARGET_ABI_DIR' not in config_target
1247 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1250 foreach k, v: disassemblers
1251 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1253 config_target += { sym: 'y' }
1254 config_all_disas += { sym: 'y' }
1259 config_target_data = configuration_data()
1260 foreach k, v: config_target
1261 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1263 elif ignored.contains(k)
1265 elif k == 'TARGET_BASE_ARCH'
1266 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1267 # not used to select files from sourcesets.
1268 config_target_data.set('TARGET_' + v.to_upper(), 1)
1269 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1270 config_target_data.set_quoted(k, v)
1272 config_target_data.set(k, 1)
1274 config_target_data.set(k, v)
1277 config_target_h += {target: configure_file(output: target + '-config-target.h',
1278 configuration: config_target_data)}
1280 if target.endswith('-softmmu')
1281 config_devices_mak = target + '-config-devices.mak'
1282 config_devices_mak = configure_file(
1283 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1284 output: config_devices_mak,
1285 depfile: config_devices_mak + '.d',
1287 command: [minikconf,
1288 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1289 config_devices_mak, '@DEPFILE@', '@INPUT@',
1290 host_kconfig, accel_kconfig])
1292 config_devices_data = configuration_data()
1293 config_devices = keyval.load(config_devices_mak)
1294 foreach k, v: config_devices
1295 config_devices_data.set(k, 1)
1297 config_devices_mak_list += config_devices_mak
1298 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1299 configuration: config_devices_data)}
1300 config_target += config_devices
1301 config_all_devices += config_devices
1303 config_target_mak += {target: config_target}
1305 target_dirs = actual_target_dirs
1307 # This configuration is used to build files that are shared by
1308 # multiple binaries, and then extracted out of the "common"
1309 # static_library target.
1311 # We do not use all_sources()/all_dependencies(), because it would
1312 # build literally all source files, including devices only used by
1313 # targets that are not built for this compilation. The CONFIG_ALL
1314 # pseudo symbol replaces it.
1316 config_all += config_all_devices
1317 config_all += config_host
1318 config_all += config_all_disas
1320 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1321 'CONFIG_SOFTMMU': have_system,
1322 'CONFIG_USER_ONLY': have_user,
1330 capstone = not_found
1331 capstone_opt = get_option('capstone')
1332 if capstone_opt in ['enabled', 'auto', 'system']
1333 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1334 capstone = dependency('capstone', version: '>=4.0',
1335 static: enable_static, method: 'pkg-config',
1336 required: capstone_opt == 'system' or
1337 capstone_opt == 'enabled' and not have_internal)
1339 capstone_opt = 'system'
1341 capstone_opt = 'internal'
1343 capstone_opt = 'disabled'
1346 if capstone_opt == 'internal'
1347 capstone_data = configuration_data()
1348 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1350 capstone_files = files(
1352 'capstone/MCInst.c',
1353 'capstone/MCInstrDesc.c',
1354 'capstone/MCRegisterInfo.c',
1355 'capstone/SStream.c',
1359 if 'CONFIG_ARM_DIS' in config_all_disas
1360 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1361 capstone_files += files(
1362 'capstone/arch/ARM/ARMDisassembler.c',
1363 'capstone/arch/ARM/ARMInstPrinter.c',
1364 'capstone/arch/ARM/ARMMapping.c',
1365 'capstone/arch/ARM/ARMModule.c'
1369 # FIXME: This config entry currently depends on a c++ compiler.
1370 # Which is needed for building libvixl, but not for capstone.
1371 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1372 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1373 capstone_files += files(
1374 'capstone/arch/AArch64/AArch64BaseInfo.c',
1375 'capstone/arch/AArch64/AArch64Disassembler.c',
1376 'capstone/arch/AArch64/AArch64InstPrinter.c',
1377 'capstone/arch/AArch64/AArch64Mapping.c',
1378 'capstone/arch/AArch64/AArch64Module.c'
1382 if 'CONFIG_PPC_DIS' in config_all_disas
1383 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1384 capstone_files += files(
1385 'capstone/arch/PowerPC/PPCDisassembler.c',
1386 'capstone/arch/PowerPC/PPCInstPrinter.c',
1387 'capstone/arch/PowerPC/PPCMapping.c',
1388 'capstone/arch/PowerPC/PPCModule.c'
1392 if 'CONFIG_S390_DIS' in config_all_disas
1393 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1394 capstone_files += files(
1395 'capstone/arch/SystemZ/SystemZDisassembler.c',
1396 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1397 'capstone/arch/SystemZ/SystemZMapping.c',
1398 'capstone/arch/SystemZ/SystemZModule.c',
1399 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1403 if 'CONFIG_I386_DIS' in config_all_disas
1404 capstone_data.set('CAPSTONE_HAS_X86', 1)
1405 capstone_files += files(
1406 'capstone/arch/X86/X86Disassembler.c',
1407 'capstone/arch/X86/X86DisassemblerDecoder.c',
1408 'capstone/arch/X86/X86ATTInstPrinter.c',
1409 'capstone/arch/X86/X86IntelInstPrinter.c',
1410 'capstone/arch/X86/X86InstPrinterCommon.c',
1411 'capstone/arch/X86/X86Mapping.c',
1412 'capstone/arch/X86/X86Module.c'
1416 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1419 # FIXME: There does not seem to be a way to completely replace the c_args
1420 # that come from add_project_arguments() -- we can only add to them.
1421 # So: disable all warnings with a big hammer.
1424 # Include all configuration defines via a header file, which will wind up
1425 # as a dependency on the object file, and thus changes here will result
1427 '-include', 'capstone-defs.h'
1430 libcapstone = static_library('capstone',
1431 sources: capstone_files,
1432 c_args: capstone_cargs,
1433 include_directories: 'capstone/include')
1434 capstone = declare_dependency(link_with: libcapstone,
1435 include_directories: 'capstone/include/capstone')
1439 slirp_opt = 'disabled'
1441 slirp_opt = get_option('slirp')
1442 if slirp_opt in ['enabled', 'auto', 'system']
1443 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1444 slirp = dependency('slirp', static: enable_static,
1445 method: 'pkg-config',
1446 required: slirp_opt == 'system' or
1447 slirp_opt == 'enabled' and not have_internal)
1449 slirp_opt = 'system'
1451 slirp_opt = 'internal'
1453 slirp_opt = 'disabled'
1456 if slirp_opt == 'internal'
1458 if targetos == 'windows'
1459 slirp_deps = cc.find_library('iphlpapi')
1461 slirp_conf = configuration_data()
1462 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1463 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1464 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1465 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1466 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1468 'slirp/src/arp_table.c',
1469 'slirp/src/bootp.c',
1470 'slirp/src/cksum.c',
1471 'slirp/src/dhcpv6.c',
1472 'slirp/src/dnssearch.c',
1474 'slirp/src/ip6_icmp.c',
1475 'slirp/src/ip6_input.c',
1476 'slirp/src/ip6_output.c',
1477 'slirp/src/ip_icmp.c',
1478 'slirp/src/ip_input.c',
1479 'slirp/src/ip_output.c',
1483 'slirp/src/ndp_table.c',
1485 'slirp/src/slirp.c',
1486 'slirp/src/socket.c',
1487 'slirp/src/state.c',
1488 'slirp/src/stream.c',
1489 'slirp/src/tcp_input.c',
1490 'slirp/src/tcp_output.c',
1491 'slirp/src/tcp_subr.c',
1492 'slirp/src/tcp_timer.c',
1497 'slirp/src/version.c',
1498 'slirp/src/vmstate.c',
1502 input : 'slirp/src/libslirp-version.h.in',
1503 output : 'libslirp-version.h',
1504 configuration: slirp_conf)
1506 slirp_inc = include_directories('slirp', 'slirp/src')
1507 libslirp = static_library('slirp',
1508 sources: slirp_files,
1509 c_args: slirp_cargs,
1510 include_directories: slirp_inc)
1511 slirp = declare_dependency(link_with: libslirp,
1512 dependencies: slirp_deps,
1513 include_directories: slirp_inc)
1518 fdt_opt = get_option('fdt')
1520 if fdt_opt in ['enabled', 'auto', 'system']
1521 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1522 fdt = cc.find_library('fdt', static: enable_static,
1523 required: fdt_opt == 'system' or
1524 fdt_opt == 'enabled' and not have_internal)
1525 if fdt.found() and cc.links('''
1527 #include <libfdt_env.h>
1528 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1532 fdt_opt = 'internal'
1534 fdt_opt = 'disabled'
1537 if fdt_opt == 'internal'
1540 'dtc/libfdt/fdt_ro.c',
1541 'dtc/libfdt/fdt_wip.c',
1542 'dtc/libfdt/fdt_sw.c',
1543 'dtc/libfdt/fdt_rw.c',
1544 'dtc/libfdt/fdt_strerror.c',
1545 'dtc/libfdt/fdt_empty_tree.c',
1546 'dtc/libfdt/fdt_addresses.c',
1547 'dtc/libfdt/fdt_overlay.c',
1548 'dtc/libfdt/fdt_check.c',
1551 fdt_inc = include_directories('dtc/libfdt')
1552 libfdt = static_library('fdt',
1554 include_directories: fdt_inc)
1555 fdt = declare_dependency(link_with: libfdt,
1556 include_directories: fdt_inc)
1559 if not fdt.found() and fdt_required.length() > 0
1560 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1563 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1564 config_host_data.set('CONFIG_FDT', fdt.found())
1565 config_host_data.set('CONFIG_SLIRP', slirp.found())
1567 #####################
1568 # Generated sources #
1569 #####################
1571 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1573 hxtool = find_program('scripts/hxtool')
1574 shaderinclude = find_program('scripts/shaderinclude.pl')
1575 qapi_gen = find_program('scripts/qapi-gen.py')
1576 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1577 meson.source_root() / 'scripts/qapi/commands.py',
1578 meson.source_root() / 'scripts/qapi/common.py',
1579 meson.source_root() / 'scripts/qapi/error.py',
1580 meson.source_root() / 'scripts/qapi/events.py',
1581 meson.source_root() / 'scripts/qapi/expr.py',
1582 meson.source_root() / 'scripts/qapi/gen.py',
1583 meson.source_root() / 'scripts/qapi/introspect.py',
1584 meson.source_root() / 'scripts/qapi/parser.py',
1585 meson.source_root() / 'scripts/qapi/schema.py',
1586 meson.source_root() / 'scripts/qapi/source.py',
1587 meson.source_root() / 'scripts/qapi/types.py',
1588 meson.source_root() / 'scripts/qapi/visit.py',
1589 meson.source_root() / 'scripts/qapi/common.py',
1590 meson.source_root() / 'scripts/qapi-gen.py'
1594 python, files('scripts/tracetool.py'),
1595 '--backend=' + config_host['TRACE_BACKENDS']
1598 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1599 meson.current_source_dir(),
1600 config_host['PKGVERSION'], meson.project_version()]
1601 qemu_version = custom_target('qemu-version.h',
1602 output: 'qemu-version.h',
1603 command: qemu_version_cmd,
1605 build_by_default: true,
1606 build_always_stale: true)
1607 genh += qemu_version
1611 ['qemu-options.hx', 'qemu-options.def'],
1612 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1616 ['hmp-commands.hx', 'hmp-commands.h'],
1617 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1620 foreach d : hx_headers
1621 hxdep += custom_target(d[1],
1625 build_by_default: true, # to be removed when added to a target
1626 command: [hxtool, '-h', '@INPUT0@'])
1634 authz_ss = ss.source_set()
1635 blockdev_ss = ss.source_set()
1636 block_ss = ss.source_set()
1637 bsd_user_ss = ss.source_set()
1638 chardev_ss = ss.source_set()
1639 common_ss = ss.source_set()
1640 crypto_ss = ss.source_set()
1641 io_ss = ss.source_set()
1642 linux_user_ss = ss.source_set()
1643 qmp_ss = ss.source_set()
1644 qom_ss = ss.source_set()
1645 softmmu_ss = ss.source_set()
1646 specific_fuzz_ss = ss.source_set()
1647 specific_ss = ss.source_set()
1648 stub_ss = ss.source_set()
1649 trace_ss = ss.source_set()
1650 user_ss = ss.source_set()
1651 util_ss = ss.source_set()
1656 target_softmmu_arch = {}
1662 # TODO: add each directory to the subdirs from its own meson.build, once
1664 trace_events_subdirs = [
1671 trace_events_subdirs += [ 'linux-user' ]
1674 trace_events_subdirs += [
1683 trace_events_subdirs += [
1694 'hw/block/dataplane',
1740 trace_events_subdirs += [
1756 vhost_user = not_found
1757 if 'CONFIG_VHOST_USER' in config_host
1758 libvhost_user = subproject('libvhost-user')
1759 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1774 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1775 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1778 stub_ss = stub_ss.apply(config_all, strict: false)
1780 util_ss.add_all(trace_ss)
1781 util_ss = util_ss.apply(config_all, strict: false)
1782 libqemuutil = static_library('qemuutil',
1783 sources: util_ss.sources() + stub_ss.sources() + genh,
1784 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1785 qemuutil = declare_dependency(link_with: libqemuutil,
1786 sources: genh + version_res)
1788 decodetree = generator(find_program('scripts/decodetree.py'),
1789 output: 'decode-@BASENAME@.c.inc',
1790 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1796 subdir('libdecnumber')
1806 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1812 blockdev_ss.add(files(
1819 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1820 # os-win32.c does not
1821 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1822 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1824 common_ss.add(files('cpus-common.c'))
1828 common_ss.add(capstone)
1829 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1830 specific_ss.add(files('exec-vary.c'))
1831 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1835 'tcg/tcg-op-gvec.c',
1840 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1852 subdir('linux-user')
1854 bsd_user_ss.add(files('gdbstub.c'))
1855 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1857 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1858 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1860 # needed for fuzzing binaries
1861 subdir('tests/qtest/libqos')
1862 subdir('tests/qtest/fuzz')
1864 ########################
1865 # Library dependencies #
1866 ########################
1870 foreach d, list : modules
1871 foreach m, module_ss : list
1872 if enable_modules and targetos != 'windows'
1873 module_ss = module_ss.apply(config_all, strict: false)
1874 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1875 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1883 block_ss.add_all(module_ss)
1885 softmmu_ss.add_all(module_ss)
1891 nm = find_program('nm')
1892 undefsym = find_program('scripts/undefsym.py')
1893 block_syms = custom_target('block.syms', output: 'block.syms',
1894 input: [libqemuutil, block_mods],
1896 command: [undefsym, nm, '@INPUT@'])
1897 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1898 input: [libqemuutil, softmmu_mods],
1900 command: [undefsym, nm, '@INPUT@'])
1902 qom_ss = qom_ss.apply(config_host, strict: false)
1903 libqom = static_library('qom', qom_ss.sources() + genh,
1904 dependencies: [qom_ss.dependencies()],
1907 qom = declare_dependency(link_whole: libqom)
1909 authz_ss = authz_ss.apply(config_host, strict: false)
1910 libauthz = static_library('authz', authz_ss.sources() + genh,
1911 dependencies: [authz_ss.dependencies()],
1913 build_by_default: false)
1915 authz = declare_dependency(link_whole: libauthz,
1918 crypto_ss = crypto_ss.apply(config_host, strict: false)
1919 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1920 dependencies: [crypto_ss.dependencies()],
1922 build_by_default: false)
1924 crypto = declare_dependency(link_whole: libcrypto,
1925 dependencies: [authz, qom])
1927 io_ss = io_ss.apply(config_host, strict: false)
1928 libio = static_library('io', io_ss.sources() + genh,
1929 dependencies: [io_ss.dependencies()],
1930 link_with: libqemuutil,
1932 build_by_default: false)
1934 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1936 libmigration = static_library('migration', sources: migration_files + genh,
1938 build_by_default: false)
1939 migration = declare_dependency(link_with: libmigration,
1940 dependencies: [zlib, qom, io])
1941 softmmu_ss.add(migration)
1943 block_ss = block_ss.apply(config_host, strict: false)
1944 libblock = static_library('block', block_ss.sources() + genh,
1945 dependencies: block_ss.dependencies(),
1946 link_depends: block_syms,
1948 build_by_default: false)
1950 block = declare_dependency(link_whole: [libblock],
1951 link_args: '@block.syms',
1952 dependencies: [crypto, io])
1954 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1955 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1956 dependencies: blockdev_ss.dependencies(),
1958 build_by_default: false)
1960 blockdev = declare_dependency(link_whole: [libblockdev],
1961 dependencies: [block])
1963 qmp_ss = qmp_ss.apply(config_host, strict: false)
1964 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1965 dependencies: qmp_ss.dependencies(),
1967 build_by_default: false)
1969 qmp = declare_dependency(link_whole: [libqmp])
1971 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1973 build_by_default: false)
1975 chardev = declare_dependency(link_whole: libchardev)
1977 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1979 build_by_default: false)
1980 hwcore = declare_dependency(link_whole: libhwcore)
1981 common_ss.add(hwcore)
1987 foreach m : block_mods + softmmu_mods
1988 shared_module(m.name(),
1992 install_dir: qemu_moddir)
1995 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1996 common_ss.add(qom, qemuutil)
1998 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1999 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2001 common_all = common_ss.apply(config_all, strict: false)
2002 common_all = static_library('common',
2003 build_by_default: false,
2004 sources: common_all.sources() + genh,
2005 dependencies: common_all.dependencies(),
2008 feature_to_c = find_program('scripts/feature_to_c.sh')
2011 foreach target : target_dirs
2012 config_target = config_target_mak[target]
2013 target_name = config_target['TARGET_NAME']
2014 arch = config_target['TARGET_BASE_ARCH']
2015 arch_srcs = [config_target_h[target]]
2017 c_args = ['-DNEED_CPU_H',
2018 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2019 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2020 link_args = emulator_link_args
2022 config_target += config_host
2023 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2024 if targetos == 'linux'
2025 target_inc += include_directories('linux-headers', is_system: true)
2027 if target.endswith('-softmmu')
2028 qemu_target_name = 'qemu-system-' + target_name
2029 target_type='system'
2030 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2031 arch_srcs += t.sources()
2032 arch_deps += t.dependencies()
2034 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2035 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2036 arch_srcs += hw.sources()
2037 arch_deps += hw.dependencies()
2039 arch_srcs += config_devices_h[target]
2040 link_args += ['@block.syms', '@qemu.syms']
2042 abi = config_target['TARGET_ABI_DIR']
2044 qemu_target_name = 'qemu-' + target_name
2045 if 'CONFIG_LINUX_USER' in config_target
2046 base_dir = 'linux-user'
2047 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2049 base_dir = 'bsd-user'
2051 target_inc += include_directories(
2055 if 'CONFIG_LINUX_USER' in config_target
2056 dir = base_dir / abi
2057 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2058 if config_target.has_key('TARGET_SYSTBL_ABI')
2060 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2061 extra_args : config_target['TARGET_SYSTBL_ABI'])
2066 if 'TARGET_XML_FILES' in config_target
2067 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2068 output: target + '-gdbstub-xml.c',
2069 input: files(config_target['TARGET_XML_FILES'].split()),
2070 command: [feature_to_c, '@INPUT@'],
2072 arch_srcs += gdbstub_xml
2075 t = target_arch[arch].apply(config_target, strict: false)
2076 arch_srcs += t.sources()
2077 arch_deps += t.dependencies()
2079 target_common = common_ss.apply(config_target, strict: false)
2080 objects = common_all.extract_objects(target_common.sources())
2081 deps = target_common.dependencies()
2083 target_specific = specific_ss.apply(config_target, strict: false)
2084 arch_srcs += target_specific.sources()
2085 arch_deps += target_specific.dependencies()
2087 lib = static_library('qemu-' + target,
2088 sources: arch_srcs + genh,
2089 dependencies: arch_deps,
2091 include_directories: target_inc,
2093 build_by_default: false,
2096 if target.endswith('-softmmu')
2098 'name': 'qemu-system-' + target_name,
2100 'sources': files('softmmu/main.c'),
2103 if targetos == 'windows' and (sdl.found() or gtk.found())
2105 'name': 'qemu-system-' + target_name + 'w',
2107 'sources': files('softmmu/main.c'),
2111 if config_host.has_key('CONFIG_FUZZ')
2112 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2114 'name': 'qemu-fuzz-' + target_name,
2116 'sources': specific_fuzz.sources(),
2117 'dependencies': specific_fuzz.dependencies(),
2122 'name': 'qemu-' + target_name,
2129 emulators += {exe['name']:
2130 executable(exe['name'], exe['sources'],
2133 dependencies: arch_deps + deps + exe['dependencies'],
2134 objects: lib.extract_all_objects(recursive: true),
2135 link_language: link_language,
2136 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2137 link_args: link_args,
2138 gui_app: exe['gui'])
2141 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2143 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2144 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2145 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2146 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2148 custom_target(exe['name'] + stp['ext'],
2149 input: trace_events_all,
2150 output: exe['name'] + stp['ext'],
2151 install: stp['install'],
2152 install_dir: get_option('datadir') / 'systemtap/tapset',
2154 tracetool, '--group=all', '--format=' + stp['fmt'],
2155 '--binary=' + stp['bin'],
2156 '--target-name=' + target_name,
2157 '--target-type=' + target_type,
2158 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2159 '@INPUT@', '@OUTPUT@'
2166 # Other build targets
2168 if 'CONFIG_PLUGIN' in config_host
2169 install_headers('include/qemu/qemu-plugin.h')
2172 if 'CONFIG_GUEST_AGENT' in config_host
2176 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2177 # when we don't build tools or system
2178 if xkbcommon.found()
2179 # used for the update-keymaps target, so include rules even if !have_tools
2180 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2181 dependencies: [qemuutil, xkbcommon], install: have_tools)
2185 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2186 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2187 qemu_io = executable('qemu-io', files('qemu-io.c'),
2188 dependencies: [block, qemuutil], install: true)
2189 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2190 dependencies: [blockdev, qemuutil], install: true)
2192 subdir('storage-daemon')
2193 subdir('contrib/rdmacm-mux')
2194 subdir('contrib/elf2dmp')
2196 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2197 dependencies: qemuutil,
2200 if 'CONFIG_VHOST_USER' in config_host
2201 subdir('contrib/vhost-user-blk')
2202 subdir('contrib/vhost-user-gpu')
2203 subdir('contrib/vhost-user-input')
2204 subdir('contrib/vhost-user-scsi')
2207 if targetos == 'linux'
2208 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2209 dependencies: [qemuutil, libcap_ng],
2211 install_dir: get_option('libexecdir'))
2213 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2214 dependencies: [authz, crypto, io, qom, qemuutil,
2215 libcap_ng, mpathpersist],
2219 if 'CONFIG_IVSHMEM' in config_host
2220 subdir('contrib/ivshmem-client')
2221 subdir('contrib/ivshmem-server')
2230 if 'CONFIG_GTK' in config_host
2234 if host_machine.system() == 'windows'
2236 find_program('scripts/nsis.py'),
2238 get_option('prefix'),
2239 meson.current_source_dir(),
2242 '-DDISPLAYVERSION=' + meson.project_version(),
2245 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2247 if 'CONFIG_GTK' in config_host
2248 nsis_cmd += '-DCONFIG_GTK=y'
2251 nsis = custom_target('nsis',
2252 output: 'qemu-setup-' + meson.project_version() + '.exe',
2253 input: files('qemu.nsi'),
2254 build_always_stale: true,
2255 command: nsis_cmd + ['@INPUT@'])
2256 alias_target('installer', nsis)
2259 #########################
2260 # Configuration summary #
2261 #########################
2264 summary_info += {'Install prefix': get_option('prefix')}
2265 summary_info += {'BIOS directory': qemu_datadir}
2266 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2267 summary_info += {'binary directory': get_option('bindir')}
2268 summary_info += {'library directory': get_option('libdir')}
2269 summary_info += {'module directory': qemu_moddir}
2270 summary_info += {'libexec directory': get_option('libexecdir')}
2271 summary_info += {'include directory': get_option('includedir')}
2272 summary_info += {'config directory': get_option('sysconfdir')}
2273 if targetos != 'windows'
2274 summary_info += {'local state directory': get_option('localstatedir')}
2275 summary_info += {'Manual directory': get_option('mandir')}
2277 summary_info += {'local state directory': 'queried at runtime'}
2279 summary_info += {'Doc directory': get_option('docdir')}
2280 summary_info += {'Build directory': meson.current_build_dir()}
2281 summary_info += {'Source path': meson.current_source_dir()}
2282 summary_info += {'GIT binary': config_host['GIT']}
2283 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2284 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2285 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2286 if link_language == 'cpp'
2287 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2289 summary_info += {'C++ compiler': false}
2291 if targetos == 'darwin'
2292 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2294 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2295 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2296 + ['-O' + get_option('optimization')]
2297 + (get_option('debug') ? ['-g'] : []))}
2298 if link_language == 'cpp'
2299 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2300 + ['-O' + get_option('optimization')]
2301 + (get_option('debug') ? ['-g'] : []))}
2303 link_args = get_option(link_language + '_link_args')
2304 if link_args.length() > 0
2305 summary_info += {'LDFLAGS': ' '.join(link_args)}
2307 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2308 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2309 summary_info += {'make': config_host['MAKE']}
2310 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2311 summary_info += {'sphinx-build': sphinx_build.found()}
2312 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2313 # TODO: add back version
2314 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2315 if slirp_opt != 'disabled'
2316 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2318 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2319 if config_host.has_key('CONFIG_MODULES')
2320 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2322 summary_info += {'host CPU': cpu}
2323 summary_info += {'host endianness': build_machine.endian()}
2324 summary_info += {'target list': ' '.join(target_dirs)}
2325 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2326 summary_info += {'sparse enabled': sparse.found()}
2327 summary_info += {'strip binaries': get_option('strip')}
2328 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2329 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2330 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2331 if targetos == 'darwin'
2332 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2334 # TODO: add back version
2335 summary_info += {'SDL support': sdl.found()}
2336 summary_info += {'SDL image support': sdl_image.found()}
2337 # TODO: add back version
2338 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
2339 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
2340 summary_info += {'pixman': pixman.found()}
2341 # TODO: add back version
2342 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2343 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2344 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2345 # TODO: add back version
2346 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2347 if config_host.has_key('CONFIG_GCRYPT')
2348 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2349 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2351 # TODO: add back version
2352 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2353 if config_host.has_key('CONFIG_NETTLE')
2354 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2356 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2357 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2358 summary_info += {'iconv support': iconv.found()}
2359 summary_info += {'curses support': curses.found()}
2360 # TODO: add back version
2361 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2362 summary_info += {'curl support': curl.found()}
2363 summary_info += {'mingw32 support': targetos == 'windows'}
2364 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2365 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2366 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2367 summary_info += {'VirtFS support': have_virtfs}
2368 summary_info += {'build virtiofs daemon': have_virtiofsd}
2369 summary_info += {'Multipath support': mpathpersist.found()}
2370 summary_info += {'VNC support': vnc.found()}
2372 summary_info += {'VNC SASL support': sasl.found()}
2373 summary_info += {'VNC JPEG support': jpeg.found()}
2374 summary_info += {'VNC PNG support': png.found()}
2376 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2377 if config_host.has_key('CONFIG_XEN_BACKEND')
2378 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2380 summary_info += {'brlapi support': brlapi.found()}
2381 summary_info += {'Documentation': build_docs}
2382 summary_info += {'PIE': get_option('b_pie')}
2383 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2384 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2385 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2386 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2387 summary_info += {'ATTR/XATTR support': libattr.found()}
2388 summary_info += {'Install blobs': get_option('install_blobs')}
2389 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2390 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2391 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2392 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2393 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2394 if config_all.has_key('CONFIG_TCG')
2395 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2396 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
2398 summary_info += {'malloc trim support': has_malloc_trim}
2399 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2400 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2401 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2402 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2403 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2404 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2405 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2406 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2407 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2408 summary_info += {'libcap-ng support': libcap_ng.found()}
2409 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2410 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2411 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2412 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2413 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2414 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2415 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2416 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2417 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2418 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2419 if config_host['TRACE_BACKENDS'].split().contains('simple')
2420 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2422 # TODO: add back protocol and server version
2423 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2424 summary_info += {'rbd support': rbd.found()}
2425 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2426 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2427 summary_info += {'U2F support': u2f.found()}
2428 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2429 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2430 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2431 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2432 summary_info += {'libiscsi support': libiscsi.found()}
2433 summary_info += {'libnfs support': libnfs.found()}
2434 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2435 if targetos == 'windows'
2436 if 'WIN_SDK' in config_host
2437 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2439 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2440 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2441 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2443 summary_info += {'seccomp support': seccomp.found()}
2444 summary_info += {'CFI support': get_option('cfi')}
2445 summary_info += {'CFI debug support': get_option('cfi_debug')}
2446 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2447 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2448 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2449 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2450 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2451 summary_info += {'GlusterFS support': glusterfs.found()}
2452 summary_info += {'gcov': get_option('b_coverage')}
2453 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2454 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2455 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2456 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2457 summary_info += {'lzo support': lzo.found()}
2458 summary_info += {'snappy support': snappy.found()}
2459 summary_info += {'bzip2 support': libbzip2.found()}
2460 summary_info += {'lzfse support': liblzfse.found()}
2461 summary_info += {'zstd support': zstd.found()}
2462 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2463 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2464 summary_info += {'memory allocator': get_option('malloc')}
2465 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2466 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
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 += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2478 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2479 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2480 summary_info += {'libudev': libudev.found()}
2481 summary_info += {'default devices': get_option('default_devices')}
2482 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2483 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2484 if config_host.has_key('HAVE_GDB_BIN')
2485 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2487 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2488 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2489 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2490 summary_info += {'FUSE exports': fuse.found()}
2491 summary_info += {'FUSE lseek': fuse_lseek.found()}
2492 summary(summary_info, bool_yn: true)
2494 if not supported_cpus.contains(cpu)
2496 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2498 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2499 message('The QEMU project intends to remove support for this host CPU in')
2500 message('a future release if nobody volunteers to maintain it and to')
2501 message('provide a build host for our continuous integration setup.')
2502 message('configure has succeeded and you can continue to build, but')
2503 message('if you care about QEMU on this platform you should contact')
2504 message('us upstream at qemu-devel@nongnu.org.')
2507 if not supported_oses.contains(targetos)
2509 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2511 message('Host OS ' + targetos + 'support is not currently maintained.')
2512 message('The QEMU project intends to remove support for this host OS in')
2513 message('a future release if nobody volunteers to maintain it and to')
2514 message('provide a build host for our continuous integration setup.')
2515 message('configure has succeeded and you can continue to build, but')
2516 message('if you care about QEMU on this platform you should contact')
2517 message('us upstream at qemu-devel@nongnu.org.')