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())
782 if not get_option('gtk').auto() or have_system
783 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
784 method: 'pkg-config',
785 required: get_option('gtk'),
786 static: enable_static)
788 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
789 method: 'pkg-config',
791 static: enable_static)
792 gtk = declare_dependency(dependencies: [gtk, gtkx11])
797 if 'CONFIG_VTE' in config_host
798 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
799 link_args: config_host['VTE_LIBS'].split())
802 if gtkx11.found() or 'lm32-softmmu' in target_dirs
803 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
804 static: enable_static)
810 if get_option('vnc').enabled()
811 vnc = declare_dependency() # dummy dependency
812 png = dependency('libpng', required: get_option('vnc_png'),
813 method: 'pkg-config', static: enable_static)
814 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
815 method: 'pkg-config', static: enable_static)
816 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
817 required: get_option('vnc_sasl'),
818 static: enable_static)
820 sasl = declare_dependency(dependencies: sasl,
821 compile_args: '-DSTRUCT_IOVEC_DEFINED')
826 if not get_option('snappy').auto() or have_system
827 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
828 required: get_option('snappy'),
829 static: enable_static)
831 if snappy.found() and not cc.links('''
832 #include <snappy-c.h>
833 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
835 if get_option('snappy').enabled()
836 error('could not link libsnappy')
838 warning('could not link libsnappy, disabling')
843 if not get_option('lzo').auto() or have_system
844 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
845 required: get_option('lzo'),
846 static: enable_static)
848 if lzo.found() and not cc.links('''
849 #include <lzo/lzo1x.h>
850 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
852 if get_option('lzo').enabled()
853 error('could not link liblzo2')
855 warning('could not link liblzo2, disabling')
860 if 'CONFIG_RDMA' in config_host
861 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
864 if 'CONFIG_NUMA' in config_host
865 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
868 if 'CONFIG_XEN_BACKEND' in config_host
869 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
870 link_args: config_host['XEN_LIBS'].split())
873 if 'CONFIG_SMARTCARD' in config_host
874 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
875 link_args: config_host['SMARTCARD_LIBS'].split())
879 u2f = dependency('u2f-emu', required: get_option('u2f'),
880 method: 'pkg-config',
881 static: enable_static)
884 if 'CONFIG_USB_REDIR' in config_host
885 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
886 link_args: config_host['USB_REDIR_LIBS'].split())
889 if 'CONFIG_USB_LIBUSB' in config_host
890 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
891 link_args: config_host['LIBUSB_LIBS'].split())
894 if 'CONFIG_LIBPMEM' in config_host
895 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
896 link_args: config_host['LIBPMEM_LIBS'].split())
898 libdaxctl = not_found
899 if 'CONFIG_LIBDAXCTL' in config_host
900 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
903 if 'CONFIG_TASN1' in config_host
904 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
905 link_args: config_host['TASN1_LIBS'].split())
907 keyutils = dependency('libkeyutils', required: false,
908 method: 'pkg-config', static: enable_static)
910 has_gettid = cc.has_function('gettid')
915 if get_option('malloc') == 'system'
917 not get_option('malloc_trim').disabled() and \
918 cc.links('''#include <malloc.h>
919 int main(void) { malloc_trim(0); return 0; }''')
921 has_malloc_trim = false
922 malloc = cc.find_library(get_option('malloc'), required: true)
924 if not has_malloc_trim and get_option('malloc_trim').enabled()
925 if get_option('malloc') == 'system'
926 error('malloc_trim not available on this platform.')
928 error('malloc_trim not available with non-libc memory allocator')
932 # Check whether the glibc provides statx()
938 #include <sys/stat.h>
940 struct statx statxbuf;
941 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
945 has_statx = cc.links(statx_test)
947 have_vhost_user_blk_server = (targetos == 'linux' and
948 'CONFIG_VHOST_USER' in config_host)
950 if get_option('vhost_user_blk_server').enabled()
951 if targetos != 'linux'
952 error('vhost_user_blk_server requires linux')
953 elif 'CONFIG_VHOST_USER' not in config_host
954 error('vhost_user_blk_server requires vhost-user support')
956 elif get_option('vhost_user_blk_server').disabled() or not have_system
957 have_vhost_user_blk_server = false
961 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
962 error('Cannot enable fuse-lseek while fuse is disabled')
965 fuse = dependency('fuse3', required: get_option('fuse'),
966 version: '>=3.1', method: 'pkg-config',
967 static: enable_static)
969 fuse_lseek = not_found
970 if not get_option('fuse_lseek').disabled()
971 if fuse.version().version_compare('>=3.8')
973 fuse_lseek = declare_dependency()
974 elif get_option('fuse_lseek').enabled()
976 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
978 error('fuse-lseek requires libfuse, which was not found')
985 # Check for dependency on LTO
986 if not get_option('b_lto')
987 error('Selected Control-Flow Integrity but LTO is disabled')
989 if config_host.has_key('CONFIG_MODULES')
990 error('Selected Control-Flow Integrity is not compatible with modules')
992 # Check for cfi flags. CFI requires LTO so we can't use
993 # get_supported_arguments, but need a more complex "compiles" which allows
995 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
996 args: ['-flto', '-fsanitize=cfi-icall'] )
997 cfi_flags += '-fsanitize=cfi-icall'
999 error('-fsanitize=cfi-icall is not supported by the compiler')
1001 if cc.compiles('int main () { return 0; }',
1002 name: '-fsanitize-cfi-icall-generalize-pointers',
1003 args: ['-flto', '-fsanitize=cfi-icall',
1004 '-fsanitize-cfi-icall-generalize-pointers'] )
1005 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1007 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1009 if get_option('cfi_debug')
1010 if cc.compiles('int main () { return 0; }',
1011 name: '-fno-sanitize-trap=cfi-icall',
1012 args: ['-flto', '-fsanitize=cfi-icall',
1013 '-fno-sanitize-trap=cfi-icall'] )
1014 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1016 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1019 add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1020 add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1027 have_virtfs = (targetos == 'linux' and
1032 if get_option('virtfs').enabled()
1034 if targetos != 'linux'
1035 error('virtio-9p (virtfs) requires Linux')
1036 elif not libcap_ng.found() or not libattr.found()
1037 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1038 elif not have_system
1039 error('virtio-9p (virtfs) needs system emulation support')
1042 elif get_option('virtfs').disabled()
1046 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1047 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1048 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1049 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1050 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1051 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1052 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1053 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1054 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1055 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1056 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1057 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1059 config_host_data.set('CONFIG_ATTR', libattr.found())
1060 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1061 config_host_data.set('CONFIG_COCOA', cocoa.found())
1062 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1063 config_host_data.set('CONFIG_LZO', lzo.found())
1064 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1065 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1066 config_host_data.set('CONFIG_CURL', curl.found())
1067 config_host_data.set('CONFIG_CURSES', curses.found())
1068 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1069 if glusterfs.found()
1070 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1071 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1072 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1073 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1074 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1075 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1077 config_host_data.set('CONFIG_GTK', gtk.found())
1078 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1079 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1080 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1081 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1082 config_host_data.set('CONFIG_RBD', rbd.found())
1083 config_host_data.set('CONFIG_SDL', sdl.found())
1084 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1085 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1086 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1087 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1088 config_host_data.set('CONFIG_VNC', vnc.found())
1089 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1090 config_host_data.set('CONFIG_VNC_PNG', png.found())
1091 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1092 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1093 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1094 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1095 config_host_data.set('CONFIG_GETTID', has_gettid)
1096 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1097 config_host_data.set('CONFIG_STATX', has_statx)
1098 config_host_data.set('CONFIG_ZSTD', zstd.found())
1099 config_host_data.set('CONFIG_FUSE', fuse.found())
1100 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1101 config_host_data.set('CONFIG_X11', x11.found())
1102 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1103 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1104 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1105 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1106 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1108 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1109 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1110 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1111 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1112 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1113 config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
1115 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1116 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1117 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1118 foreach k, v: config_host
1119 if ignored.contains(k)
1121 elif arrays.contains(k)
1123 v = '"' + '", "'.join(v.split()) + '", '
1125 config_host_data.set(k, v)
1127 config_host_data.set('HOST_' + v.to_upper(), 1)
1128 elif strings.contains(k)
1129 if not k.startswith('CONFIG_')
1130 k = 'CONFIG_' + k.to_upper()
1132 config_host_data.set_quoted(k, v)
1133 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1134 config_host_data.set(k, v == 'y' ? 1 : v)
1138 ########################
1139 # Target configuration #
1140 ########################
1142 minikconf = find_program('scripts/minikconf.py')
1144 config_all_devices = {}
1145 config_all_disas = {}
1146 config_devices_mak_list = []
1147 config_devices_h = {}
1148 config_target_h = {}
1149 config_target_mak = {}
1152 'alpha' : ['CONFIG_ALPHA_DIS'],
1153 'arm' : ['CONFIG_ARM_DIS'],
1154 'avr' : ['CONFIG_AVR_DIS'],
1155 'cris' : ['CONFIG_CRIS_DIS'],
1156 'hppa' : ['CONFIG_HPPA_DIS'],
1157 'i386' : ['CONFIG_I386_DIS'],
1158 'x86_64' : ['CONFIG_I386_DIS'],
1159 'x32' : ['CONFIG_I386_DIS'],
1160 'lm32' : ['CONFIG_LM32_DIS'],
1161 'm68k' : ['CONFIG_M68K_DIS'],
1162 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1163 'mips' : ['CONFIG_MIPS_DIS'],
1164 'moxie' : ['CONFIG_MOXIE_DIS'],
1165 'nios2' : ['CONFIG_NIOS2_DIS'],
1166 'or1k' : ['CONFIG_OPENRISC_DIS'],
1167 'ppc' : ['CONFIG_PPC_DIS'],
1168 'riscv' : ['CONFIG_RISCV_DIS'],
1169 'rx' : ['CONFIG_RX_DIS'],
1170 's390' : ['CONFIG_S390_DIS'],
1171 'sh4' : ['CONFIG_SH4_DIS'],
1172 'sparc' : ['CONFIG_SPARC_DIS'],
1173 'xtensa' : ['CONFIG_XTENSA_DIS'],
1175 if link_language == 'cpp'
1177 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1178 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1179 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1184 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1185 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1186 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1187 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1188 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1189 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1190 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1191 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1192 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1193 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1194 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1196 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1198 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1199 actual_target_dirs = []
1201 foreach target : target_dirs
1202 config_target = { 'TARGET_NAME': target.split('-')[0] }
1203 if target.endswith('linux-user')
1204 if targetos != 'linux'
1208 error('Target @0@ is only available on a Linux host'.format(target))
1210 config_target += { 'CONFIG_LINUX_USER': 'y' }
1211 elif target.endswith('bsd-user')
1212 if 'CONFIG_BSD' not in config_host
1216 error('Target @0@ is only available on a BSD host'.format(target))
1218 config_target += { 'CONFIG_BSD_USER': 'y' }
1219 elif target.endswith('softmmu')
1220 config_target += { 'CONFIG_SOFTMMU': 'y' }
1222 if target.endswith('-user')
1224 'CONFIG_USER_ONLY': 'y',
1225 'CONFIG_QEMU_INTERP_PREFIX':
1226 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1231 foreach sym: accelerators
1232 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1233 config_target += { sym: 'y' }
1234 config_all += { sym: 'y' }
1235 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1236 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1238 accel_kconfig += [ sym + '=y' ]
1241 if accel_kconfig.length() == 0
1245 error('No accelerator available for target @0@'.format(target))
1248 actual_target_dirs += target
1249 config_target += keyval.load('default-configs/targets' / target + '.mak')
1250 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1252 if 'TARGET_NEED_FDT' in config_target
1253 fdt_required += target
1257 if 'TARGET_BASE_ARCH' not in config_target
1258 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1260 if 'TARGET_ABI_DIR' not in config_target
1261 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1264 foreach k, v: disassemblers
1265 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1267 config_target += { sym: 'y' }
1268 config_all_disas += { sym: 'y' }
1273 config_target_data = configuration_data()
1274 foreach k, v: config_target
1275 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1277 elif ignored.contains(k)
1279 elif k == 'TARGET_BASE_ARCH'
1280 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1281 # not used to select files from sourcesets.
1282 config_target_data.set('TARGET_' + v.to_upper(), 1)
1283 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1284 config_target_data.set_quoted(k, v)
1286 config_target_data.set(k, 1)
1288 config_target_data.set(k, v)
1291 config_target_h += {target: configure_file(output: target + '-config-target.h',
1292 configuration: config_target_data)}
1294 if target.endswith('-softmmu')
1295 config_devices_mak = target + '-config-devices.mak'
1296 config_devices_mak = configure_file(
1297 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1298 output: config_devices_mak,
1299 depfile: config_devices_mak + '.d',
1301 command: [minikconf,
1302 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1303 config_devices_mak, '@DEPFILE@', '@INPUT@',
1304 host_kconfig, accel_kconfig])
1306 config_devices_data = configuration_data()
1307 config_devices = keyval.load(config_devices_mak)
1308 foreach k, v: config_devices
1309 config_devices_data.set(k, 1)
1311 config_devices_mak_list += config_devices_mak
1312 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1313 configuration: config_devices_data)}
1314 config_target += config_devices
1315 config_all_devices += config_devices
1317 config_target_mak += {target: config_target}
1319 target_dirs = actual_target_dirs
1321 # This configuration is used to build files that are shared by
1322 # multiple binaries, and then extracted out of the "common"
1323 # static_library target.
1325 # We do not use all_sources()/all_dependencies(), because it would
1326 # build literally all source files, including devices only used by
1327 # targets that are not built for this compilation. The CONFIG_ALL
1328 # pseudo symbol replaces it.
1330 config_all += config_all_devices
1331 config_all += config_host
1332 config_all += config_all_disas
1334 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1335 'CONFIG_SOFTMMU': have_system,
1336 'CONFIG_USER_ONLY': have_user,
1344 capstone = not_found
1345 capstone_opt = get_option('capstone')
1346 if capstone_opt in ['enabled', 'auto', 'system']
1347 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1348 capstone = dependency('capstone', version: '>=4.0',
1349 static: enable_static, method: 'pkg-config',
1350 required: capstone_opt == 'system' or
1351 capstone_opt == 'enabled' and not have_internal)
1353 capstone_opt = 'system'
1355 capstone_opt = 'internal'
1357 capstone_opt = 'disabled'
1360 if capstone_opt == 'internal'
1361 capstone_data = configuration_data()
1362 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1364 capstone_files = files(
1366 'capstone/MCInst.c',
1367 'capstone/MCInstrDesc.c',
1368 'capstone/MCRegisterInfo.c',
1369 'capstone/SStream.c',
1373 if 'CONFIG_ARM_DIS' in config_all_disas
1374 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1375 capstone_files += files(
1376 'capstone/arch/ARM/ARMDisassembler.c',
1377 'capstone/arch/ARM/ARMInstPrinter.c',
1378 'capstone/arch/ARM/ARMMapping.c',
1379 'capstone/arch/ARM/ARMModule.c'
1383 # FIXME: This config entry currently depends on a c++ compiler.
1384 # Which is needed for building libvixl, but not for capstone.
1385 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1386 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1387 capstone_files += files(
1388 'capstone/arch/AArch64/AArch64BaseInfo.c',
1389 'capstone/arch/AArch64/AArch64Disassembler.c',
1390 'capstone/arch/AArch64/AArch64InstPrinter.c',
1391 'capstone/arch/AArch64/AArch64Mapping.c',
1392 'capstone/arch/AArch64/AArch64Module.c'
1396 if 'CONFIG_PPC_DIS' in config_all_disas
1397 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1398 capstone_files += files(
1399 'capstone/arch/PowerPC/PPCDisassembler.c',
1400 'capstone/arch/PowerPC/PPCInstPrinter.c',
1401 'capstone/arch/PowerPC/PPCMapping.c',
1402 'capstone/arch/PowerPC/PPCModule.c'
1406 if 'CONFIG_S390_DIS' in config_all_disas
1407 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1408 capstone_files += files(
1409 'capstone/arch/SystemZ/SystemZDisassembler.c',
1410 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1411 'capstone/arch/SystemZ/SystemZMapping.c',
1412 'capstone/arch/SystemZ/SystemZModule.c',
1413 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1417 if 'CONFIG_I386_DIS' in config_all_disas
1418 capstone_data.set('CAPSTONE_HAS_X86', 1)
1419 capstone_files += files(
1420 'capstone/arch/X86/X86Disassembler.c',
1421 'capstone/arch/X86/X86DisassemblerDecoder.c',
1422 'capstone/arch/X86/X86ATTInstPrinter.c',
1423 'capstone/arch/X86/X86IntelInstPrinter.c',
1424 'capstone/arch/X86/X86InstPrinterCommon.c',
1425 'capstone/arch/X86/X86Mapping.c',
1426 'capstone/arch/X86/X86Module.c'
1430 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1433 # FIXME: There does not seem to be a way to completely replace the c_args
1434 # that come from add_project_arguments() -- we can only add to them.
1435 # So: disable all warnings with a big hammer.
1438 # Include all configuration defines via a header file, which will wind up
1439 # as a dependency on the object file, and thus changes here will result
1441 '-include', 'capstone-defs.h'
1444 libcapstone = static_library('capstone',
1445 sources: capstone_files,
1446 c_args: capstone_cargs,
1447 include_directories: 'capstone/include')
1448 capstone = declare_dependency(link_with: libcapstone,
1449 include_directories: 'capstone/include/capstone')
1453 slirp_opt = 'disabled'
1455 slirp_opt = get_option('slirp')
1456 if slirp_opt in ['enabled', 'auto', 'system']
1457 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1458 slirp = dependency('slirp', static: enable_static,
1459 method: 'pkg-config',
1460 required: slirp_opt == 'system' or
1461 slirp_opt == 'enabled' and not have_internal)
1463 slirp_opt = 'system'
1465 slirp_opt = 'internal'
1467 slirp_opt = 'disabled'
1470 if slirp_opt == 'internal'
1472 if targetos == 'windows'
1473 slirp_deps = cc.find_library('iphlpapi')
1475 slirp_conf = configuration_data()
1476 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1477 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1478 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1479 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1480 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1482 'slirp/src/arp_table.c',
1483 'slirp/src/bootp.c',
1484 'slirp/src/cksum.c',
1485 'slirp/src/dhcpv6.c',
1486 'slirp/src/dnssearch.c',
1488 'slirp/src/ip6_icmp.c',
1489 'slirp/src/ip6_input.c',
1490 'slirp/src/ip6_output.c',
1491 'slirp/src/ip_icmp.c',
1492 'slirp/src/ip_input.c',
1493 'slirp/src/ip_output.c',
1497 'slirp/src/ndp_table.c',
1499 'slirp/src/slirp.c',
1500 'slirp/src/socket.c',
1501 'slirp/src/state.c',
1502 'slirp/src/stream.c',
1503 'slirp/src/tcp_input.c',
1504 'slirp/src/tcp_output.c',
1505 'slirp/src/tcp_subr.c',
1506 'slirp/src/tcp_timer.c',
1511 'slirp/src/version.c',
1512 'slirp/src/vmstate.c',
1516 input : 'slirp/src/libslirp-version.h.in',
1517 output : 'libslirp-version.h',
1518 configuration: slirp_conf)
1520 slirp_inc = include_directories('slirp', 'slirp/src')
1521 libslirp = static_library('slirp',
1522 sources: slirp_files,
1523 c_args: slirp_cargs,
1524 include_directories: slirp_inc)
1525 slirp = declare_dependency(link_with: libslirp,
1526 dependencies: slirp_deps,
1527 include_directories: slirp_inc)
1532 fdt_opt = get_option('fdt')
1534 if fdt_opt in ['enabled', 'auto', 'system']
1535 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1536 fdt = cc.find_library('fdt', static: enable_static,
1537 required: fdt_opt == 'system' or
1538 fdt_opt == 'enabled' and not have_internal)
1539 if fdt.found() and cc.links('''
1541 #include <libfdt_env.h>
1542 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1546 fdt_opt = 'internal'
1548 fdt_opt = 'disabled'
1551 if fdt_opt == 'internal'
1554 'dtc/libfdt/fdt_ro.c',
1555 'dtc/libfdt/fdt_wip.c',
1556 'dtc/libfdt/fdt_sw.c',
1557 'dtc/libfdt/fdt_rw.c',
1558 'dtc/libfdt/fdt_strerror.c',
1559 'dtc/libfdt/fdt_empty_tree.c',
1560 'dtc/libfdt/fdt_addresses.c',
1561 'dtc/libfdt/fdt_overlay.c',
1562 'dtc/libfdt/fdt_check.c',
1565 fdt_inc = include_directories('dtc/libfdt')
1566 libfdt = static_library('fdt',
1568 include_directories: fdt_inc)
1569 fdt = declare_dependency(link_with: libfdt,
1570 include_directories: fdt_inc)
1573 if not fdt.found() and fdt_required.length() > 0
1574 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1577 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1578 config_host_data.set('CONFIG_FDT', fdt.found())
1579 config_host_data.set('CONFIG_SLIRP', slirp.found())
1581 #####################
1582 # Generated sources #
1583 #####################
1585 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1587 hxtool = find_program('scripts/hxtool')
1588 shaderinclude = find_program('scripts/shaderinclude.pl')
1589 qapi_gen = find_program('scripts/qapi-gen.py')
1590 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1591 meson.source_root() / 'scripts/qapi/commands.py',
1592 meson.source_root() / 'scripts/qapi/common.py',
1593 meson.source_root() / 'scripts/qapi/error.py',
1594 meson.source_root() / 'scripts/qapi/events.py',
1595 meson.source_root() / 'scripts/qapi/expr.py',
1596 meson.source_root() / 'scripts/qapi/gen.py',
1597 meson.source_root() / 'scripts/qapi/introspect.py',
1598 meson.source_root() / 'scripts/qapi/parser.py',
1599 meson.source_root() / 'scripts/qapi/schema.py',
1600 meson.source_root() / 'scripts/qapi/source.py',
1601 meson.source_root() / 'scripts/qapi/types.py',
1602 meson.source_root() / 'scripts/qapi/visit.py',
1603 meson.source_root() / 'scripts/qapi/common.py',
1604 meson.source_root() / 'scripts/qapi-gen.py'
1608 python, files('scripts/tracetool.py'),
1609 '--backend=' + config_host['TRACE_BACKENDS']
1612 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1613 meson.current_source_dir(),
1614 config_host['PKGVERSION'], meson.project_version()]
1615 qemu_version = custom_target('qemu-version.h',
1616 output: 'qemu-version.h',
1617 command: qemu_version_cmd,
1619 build_by_default: true,
1620 build_always_stale: true)
1621 genh += qemu_version
1625 ['qemu-options.hx', 'qemu-options.def'],
1626 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1630 ['hmp-commands.hx', 'hmp-commands.h'],
1631 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1634 foreach d : hx_headers
1635 hxdep += custom_target(d[1],
1639 build_by_default: true, # to be removed when added to a target
1640 command: [hxtool, '-h', '@INPUT0@'])
1648 authz_ss = ss.source_set()
1649 blockdev_ss = ss.source_set()
1650 block_ss = ss.source_set()
1651 bsd_user_ss = ss.source_set()
1652 chardev_ss = ss.source_set()
1653 common_ss = ss.source_set()
1654 crypto_ss = ss.source_set()
1655 io_ss = ss.source_set()
1656 linux_user_ss = ss.source_set()
1657 qmp_ss = ss.source_set()
1658 qom_ss = ss.source_set()
1659 softmmu_ss = ss.source_set()
1660 specific_fuzz_ss = ss.source_set()
1661 specific_ss = ss.source_set()
1662 stub_ss = ss.source_set()
1663 trace_ss = ss.source_set()
1664 user_ss = ss.source_set()
1665 util_ss = ss.source_set()
1670 target_softmmu_arch = {}
1676 # TODO: add each directory to the subdirs from its own meson.build, once
1678 trace_events_subdirs = [
1685 trace_events_subdirs += [ 'linux-user' ]
1688 trace_events_subdirs += [
1697 trace_events_subdirs += [
1708 'hw/block/dataplane',
1754 trace_events_subdirs += [
1770 vhost_user = not_found
1771 if 'CONFIG_VHOST_USER' in config_host
1772 libvhost_user = subproject('libvhost-user')
1773 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1788 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1789 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1792 stub_ss = stub_ss.apply(config_all, strict: false)
1794 util_ss.add_all(trace_ss)
1795 util_ss = util_ss.apply(config_all, strict: false)
1796 libqemuutil = static_library('qemuutil',
1797 sources: util_ss.sources() + stub_ss.sources() + genh,
1798 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1799 qemuutil = declare_dependency(link_with: libqemuutil,
1800 sources: genh + version_res)
1802 decodetree = generator(find_program('scripts/decodetree.py'),
1803 output: 'decode-@BASENAME@.c.inc',
1804 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1810 subdir('libdecnumber')
1820 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1826 blockdev_ss.add(files(
1833 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1834 # os-win32.c does not
1835 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1836 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1838 common_ss.add(files('cpus-common.c'))
1842 common_ss.add(capstone)
1843 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1844 specific_ss.add(files('exec-vary.c'))
1845 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1849 'tcg/tcg-op-gvec.c',
1854 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1866 subdir('linux-user')
1868 bsd_user_ss.add(files('gdbstub.c'))
1869 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1871 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1872 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1874 # needed for fuzzing binaries
1875 subdir('tests/qtest/libqos')
1876 subdir('tests/qtest/fuzz')
1878 ########################
1879 # Library dependencies #
1880 ########################
1884 foreach d, list : modules
1885 foreach m, module_ss : list
1886 if enable_modules and targetos != 'windows'
1887 module_ss = module_ss.apply(config_all, strict: false)
1888 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1889 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1897 block_ss.add_all(module_ss)
1899 softmmu_ss.add_all(module_ss)
1905 nm = find_program('nm')
1906 undefsym = find_program('scripts/undefsym.py')
1907 block_syms = custom_target('block.syms', output: 'block.syms',
1908 input: [libqemuutil, block_mods],
1910 command: [undefsym, nm, '@INPUT@'])
1911 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1912 input: [libqemuutil, softmmu_mods],
1914 command: [undefsym, nm, '@INPUT@'])
1916 qom_ss = qom_ss.apply(config_host, strict: false)
1917 libqom = static_library('qom', qom_ss.sources() + genh,
1918 dependencies: [qom_ss.dependencies()],
1921 qom = declare_dependency(link_whole: libqom)
1923 authz_ss = authz_ss.apply(config_host, strict: false)
1924 libauthz = static_library('authz', authz_ss.sources() + genh,
1925 dependencies: [authz_ss.dependencies()],
1927 build_by_default: false)
1929 authz = declare_dependency(link_whole: libauthz,
1932 crypto_ss = crypto_ss.apply(config_host, strict: false)
1933 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1934 dependencies: [crypto_ss.dependencies()],
1936 build_by_default: false)
1938 crypto = declare_dependency(link_whole: libcrypto,
1939 dependencies: [authz, qom])
1941 io_ss = io_ss.apply(config_host, strict: false)
1942 libio = static_library('io', io_ss.sources() + genh,
1943 dependencies: [io_ss.dependencies()],
1944 link_with: libqemuutil,
1946 build_by_default: false)
1948 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1950 libmigration = static_library('migration', sources: migration_files + genh,
1952 build_by_default: false)
1953 migration = declare_dependency(link_with: libmigration,
1954 dependencies: [zlib, qom, io])
1955 softmmu_ss.add(migration)
1957 block_ss = block_ss.apply(config_host, strict: false)
1958 libblock = static_library('block', block_ss.sources() + genh,
1959 dependencies: block_ss.dependencies(),
1960 link_depends: block_syms,
1962 build_by_default: false)
1964 block = declare_dependency(link_whole: [libblock],
1965 link_args: '@block.syms',
1966 dependencies: [crypto, io])
1968 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1969 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1970 dependencies: blockdev_ss.dependencies(),
1972 build_by_default: false)
1974 blockdev = declare_dependency(link_whole: [libblockdev],
1975 dependencies: [block])
1977 qmp_ss = qmp_ss.apply(config_host, strict: false)
1978 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1979 dependencies: qmp_ss.dependencies(),
1981 build_by_default: false)
1983 qmp = declare_dependency(link_whole: [libqmp])
1985 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1987 dependencies: [gnutls],
1988 build_by_default: false)
1990 chardev = declare_dependency(link_whole: libchardev)
1992 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1994 build_by_default: false)
1995 hwcore = declare_dependency(link_whole: libhwcore)
1996 common_ss.add(hwcore)
2002 foreach m : block_mods + softmmu_mods
2003 shared_module(m.name(),
2007 install_dir: qemu_moddir)
2010 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2011 common_ss.add(qom, qemuutil)
2013 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2014 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2016 common_all = common_ss.apply(config_all, strict: false)
2017 common_all = static_library('common',
2018 build_by_default: false,
2019 sources: common_all.sources() + genh,
2020 dependencies: common_all.dependencies(),
2023 feature_to_c = find_program('scripts/feature_to_c.sh')
2026 foreach target : target_dirs
2027 config_target = config_target_mak[target]
2028 target_name = config_target['TARGET_NAME']
2029 arch = config_target['TARGET_BASE_ARCH']
2030 arch_srcs = [config_target_h[target]]
2032 c_args = ['-DNEED_CPU_H',
2033 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2034 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2035 link_args = emulator_link_args
2037 config_target += config_host
2038 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2039 if targetos == 'linux'
2040 target_inc += include_directories('linux-headers', is_system: true)
2042 if target.endswith('-softmmu')
2043 qemu_target_name = 'qemu-system-' + target_name
2044 target_type='system'
2045 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2046 arch_srcs += t.sources()
2047 arch_deps += t.dependencies()
2049 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2050 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2051 arch_srcs += hw.sources()
2052 arch_deps += hw.dependencies()
2054 arch_srcs += config_devices_h[target]
2055 link_args += ['@block.syms', '@qemu.syms']
2057 abi = config_target['TARGET_ABI_DIR']
2059 qemu_target_name = 'qemu-' + target_name
2060 if 'CONFIG_LINUX_USER' in config_target
2061 base_dir = 'linux-user'
2062 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2064 base_dir = 'bsd-user'
2065 target_inc += include_directories('bsd-user/freebsd')
2067 target_inc += include_directories(
2071 if 'CONFIG_LINUX_USER' in config_target
2072 dir = base_dir / abi
2073 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2074 if config_target.has_key('TARGET_SYSTBL_ABI')
2076 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2077 extra_args : config_target['TARGET_SYSTBL_ABI'])
2082 if 'TARGET_XML_FILES' in config_target
2083 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2084 output: target + '-gdbstub-xml.c',
2085 input: files(config_target['TARGET_XML_FILES'].split()),
2086 command: [feature_to_c, '@INPUT@'],
2088 arch_srcs += gdbstub_xml
2091 t = target_arch[arch].apply(config_target, strict: false)
2092 arch_srcs += t.sources()
2093 arch_deps += t.dependencies()
2095 target_common = common_ss.apply(config_target, strict: false)
2096 objects = common_all.extract_objects(target_common.sources())
2097 deps = target_common.dependencies()
2099 target_specific = specific_ss.apply(config_target, strict: false)
2100 arch_srcs += target_specific.sources()
2101 arch_deps += target_specific.dependencies()
2103 lib = static_library('qemu-' + target,
2104 sources: arch_srcs + genh,
2105 dependencies: arch_deps,
2107 include_directories: target_inc,
2109 build_by_default: false,
2112 if target.endswith('-softmmu')
2114 'name': 'qemu-system-' + target_name,
2116 'sources': files('softmmu/main.c'),
2119 if targetos == 'windows' and (sdl.found() or gtk.found())
2121 'name': 'qemu-system-' + target_name + 'w',
2123 'sources': files('softmmu/main.c'),
2127 if config_host.has_key('CONFIG_FUZZ')
2128 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2130 'name': 'qemu-fuzz-' + target_name,
2132 'sources': specific_fuzz.sources(),
2133 'dependencies': specific_fuzz.dependencies(),
2138 'name': 'qemu-' + target_name,
2145 emulators += {exe['name']:
2146 executable(exe['name'], exe['sources'],
2149 dependencies: arch_deps + deps + exe['dependencies'],
2150 objects: lib.extract_all_objects(recursive: true),
2151 link_language: link_language,
2152 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2153 link_args: link_args,
2154 gui_app: exe['gui'])
2157 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2159 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2160 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2161 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2162 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2164 custom_target(exe['name'] + stp['ext'],
2165 input: trace_events_all,
2166 output: exe['name'] + stp['ext'],
2167 install: stp['install'],
2168 install_dir: get_option('datadir') / 'systemtap/tapset',
2170 tracetool, '--group=all', '--format=' + stp['fmt'],
2171 '--binary=' + stp['bin'],
2172 '--target-name=' + target_name,
2173 '--target-type=' + target_type,
2174 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2175 '@INPUT@', '@OUTPUT@'
2182 # Other build targets
2184 if 'CONFIG_PLUGIN' in config_host
2185 install_headers('include/qemu/qemu-plugin.h')
2188 if 'CONFIG_GUEST_AGENT' in config_host
2192 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2193 # when we don't build tools or system
2194 if xkbcommon.found()
2195 # used for the update-keymaps target, so include rules even if !have_tools
2196 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2197 dependencies: [qemuutil, xkbcommon], install: have_tools)
2201 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2202 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2203 qemu_io = executable('qemu-io', files('qemu-io.c'),
2204 dependencies: [block, qemuutil], install: true)
2205 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2206 dependencies: [blockdev, qemuutil, gnutls], install: true)
2208 subdir('storage-daemon')
2209 subdir('contrib/rdmacm-mux')
2210 subdir('contrib/elf2dmp')
2212 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2213 dependencies: qemuutil,
2216 if 'CONFIG_VHOST_USER' in config_host
2217 subdir('contrib/vhost-user-blk')
2218 subdir('contrib/vhost-user-gpu')
2219 subdir('contrib/vhost-user-input')
2220 subdir('contrib/vhost-user-scsi')
2223 if targetos == 'linux'
2224 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2225 dependencies: [qemuutil, libcap_ng],
2227 install_dir: get_option('libexecdir'))
2229 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2230 dependencies: [authz, crypto, io, qom, qemuutil,
2231 libcap_ng, mpathpersist],
2235 if 'CONFIG_IVSHMEM' in config_host
2236 subdir('contrib/ivshmem-client')
2237 subdir('contrib/ivshmem-server')
2250 if host_machine.system() == 'windows'
2252 find_program('scripts/nsis.py'),
2254 get_option('prefix'),
2255 meson.current_source_dir(),
2258 '-DDISPLAYVERSION=' + meson.project_version(),
2261 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2264 nsis_cmd += '-DCONFIG_GTK=y'
2267 nsis = custom_target('nsis',
2268 output: 'qemu-setup-' + meson.project_version() + '.exe',
2269 input: files('qemu.nsi'),
2270 build_always_stale: true,
2271 command: nsis_cmd + ['@INPUT@'])
2272 alias_target('installer', nsis)
2275 #########################
2276 # Configuration summary #
2277 #########################
2280 summary_info += {'Install prefix': get_option('prefix')}
2281 summary_info += {'BIOS directory': qemu_datadir}
2282 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2283 summary_info += {'binary directory': get_option('bindir')}
2284 summary_info += {'library directory': get_option('libdir')}
2285 summary_info += {'module directory': qemu_moddir}
2286 summary_info += {'libexec directory': get_option('libexecdir')}
2287 summary_info += {'include directory': get_option('includedir')}
2288 summary_info += {'config directory': get_option('sysconfdir')}
2289 if targetos != 'windows'
2290 summary_info += {'local state directory': get_option('localstatedir')}
2291 summary_info += {'Manual directory': get_option('mandir')}
2293 summary_info += {'local state directory': 'queried at runtime'}
2295 summary_info += {'Doc directory': get_option('docdir')}
2296 summary_info += {'Build directory': meson.current_build_dir()}
2297 summary_info += {'Source path': meson.current_source_dir()}
2298 summary_info += {'GIT binary': config_host['GIT']}
2299 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2300 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2301 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2302 if link_language == 'cpp'
2303 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2305 summary_info += {'C++ compiler': false}
2307 if targetos == 'darwin'
2308 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2310 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2311 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2312 + ['-O' + get_option('optimization')]
2313 + (get_option('debug') ? ['-g'] : []))}
2314 if link_language == 'cpp'
2315 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2316 + ['-O' + get_option('optimization')]
2317 + (get_option('debug') ? ['-g'] : []))}
2319 link_args = get_option(link_language + '_link_args')
2320 if link_args.length() > 0
2321 summary_info += {'LDFLAGS': ' '.join(link_args)}
2323 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2324 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2325 summary_info += {'make': config_host['MAKE']}
2326 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2327 summary_info += {'sphinx-build': sphinx_build.found()}
2328 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2329 # TODO: add back version
2330 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2331 if slirp_opt != 'disabled'
2332 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2334 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2335 if config_host.has_key('CONFIG_MODULES')
2336 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2338 summary_info += {'host CPU': cpu}
2339 summary_info += {'host endianness': build_machine.endian()}
2340 summary_info += {'target list': ' '.join(target_dirs)}
2341 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2342 summary_info += {'sparse enabled': sparse.found()}
2343 summary_info += {'strip binaries': get_option('strip')}
2344 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2345 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2346 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2347 if targetos == 'darwin'
2348 summary_info += {'Cocoa support': cocoa.found()}
2350 # TODO: add back version
2351 summary_info += {'SDL support': sdl.found()}
2352 summary_info += {'SDL image support': sdl_image.found()}
2353 # TODO: add back version
2354 summary_info += {'GTK support': gtk.found()}
2355 summary_info += {'pixman': pixman.found()}
2356 # TODO: add back version
2357 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2358 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2359 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2360 # TODO: add back version
2361 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2362 if config_host.has_key('CONFIG_GCRYPT')
2363 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2364 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2366 # TODO: add back version
2367 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2368 if config_host.has_key('CONFIG_NETTLE')
2369 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2371 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2372 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2373 summary_info += {'iconv support': iconv.found()}
2374 summary_info += {'curses support': curses.found()}
2375 # TODO: add back version
2376 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2377 summary_info += {'curl support': curl.found()}
2378 summary_info += {'mingw32 support': targetos == 'windows'}
2379 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2380 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2381 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2382 summary_info += {'VirtFS support': have_virtfs}
2383 summary_info += {'build virtiofs daemon': have_virtiofsd}
2384 summary_info += {'Multipath support': mpathpersist.found()}
2385 summary_info += {'VNC support': vnc.found()}
2387 summary_info += {'VNC SASL support': sasl.found()}
2388 summary_info += {'VNC JPEG support': jpeg.found()}
2389 summary_info += {'VNC PNG support': png.found()}
2391 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2392 if config_host.has_key('CONFIG_XEN_BACKEND')
2393 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2395 summary_info += {'brlapi support': brlapi.found()}
2396 summary_info += {'Documentation': build_docs}
2397 summary_info += {'PIE': get_option('b_pie')}
2398 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2399 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2400 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2401 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2402 summary_info += {'ATTR/XATTR support': libattr.found()}
2403 summary_info += {'Install blobs': get_option('install_blobs')}
2404 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2405 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2406 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2407 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2408 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2409 if config_all.has_key('CONFIG_TCG')
2410 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2411 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
2413 summary_info += {'malloc trim support': has_malloc_trim}
2414 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2415 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2416 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2417 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2418 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2419 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2420 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2421 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2422 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2423 summary_info += {'libcap-ng support': libcap_ng.found()}
2424 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2425 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2426 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2427 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2428 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2429 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2430 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2431 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2432 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2433 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2434 if config_host['TRACE_BACKENDS'].split().contains('simple')
2435 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2437 # TODO: add back protocol and server version
2438 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2439 summary_info += {'rbd support': rbd.found()}
2440 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2441 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2442 summary_info += {'U2F support': u2f.found()}
2443 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2444 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2445 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2446 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2447 summary_info += {'libiscsi support': libiscsi.found()}
2448 summary_info += {'libnfs support': libnfs.found()}
2449 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2450 if targetos == 'windows'
2451 if 'WIN_SDK' in config_host
2452 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2454 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2455 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2456 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2458 summary_info += {'seccomp support': seccomp.found()}
2459 summary_info += {'CFI support': get_option('cfi')}
2460 summary_info += {'CFI debug support': get_option('cfi_debug')}
2461 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2462 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2463 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2464 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2465 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2466 summary_info += {'GlusterFS support': glusterfs.found()}
2467 summary_info += {'gcov': get_option('b_coverage')}
2468 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2469 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2470 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2471 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2472 summary_info += {'lzo support': lzo.found()}
2473 summary_info += {'snappy support': snappy.found()}
2474 summary_info += {'bzip2 support': libbzip2.found()}
2475 summary_info += {'lzfse support': liblzfse.found()}
2476 summary_info += {'zstd support': zstd.found()}
2477 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2478 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2479 summary_info += {'memory allocator': get_option('malloc')}
2480 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2481 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2482 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2483 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2484 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2485 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2486 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2487 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2488 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2489 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2490 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2491 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2492 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2493 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2494 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2495 summary_info += {'libudev': libudev.found()}
2496 summary_info += {'default devices': get_option('default_devices')}
2497 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2498 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2499 if config_host.has_key('HAVE_GDB_BIN')
2500 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2502 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2503 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2504 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2505 summary_info += {'FUSE exports': fuse.found()}
2506 summary_info += {'FUSE lseek': fuse_lseek.found()}
2507 summary(summary_info, bool_yn: true)
2509 if not supported_cpus.contains(cpu)
2511 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2513 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2514 message('The QEMU project intends to remove support for this host CPU in')
2515 message('a future release if nobody volunteers to maintain it and to')
2516 message('provide a build host for our continuous integration setup.')
2517 message('configure has succeeded and you can continue to build, but')
2518 message('if you care about QEMU on this platform you should contact')
2519 message('us upstream at qemu-devel@nongnu.org.')
2522 if not supported_oses.contains(targetos)
2524 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2526 message('Host OS ' + targetos + 'support is not currently maintained.')
2527 message('The QEMU project intends to remove support for this host OS in')
2528 message('a future release if nobody volunteers to maintain it and to')
2529 message('provide a build host for our continuous integration setup.')
2530 message('configure has succeeded and you can continue to build, but')
2531 message('if you care about QEMU on this platform you should contact')
2532 message('us upstream at qemu-devel@nongnu.org.')