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 = []
173 if targetos == 'windows'
174 socket = cc.find_library('ws2_32')
175 winmm = cc.find_library('winmm')
177 win = import('windows')
178 version_res = win.compile_resources('version.rc',
179 depend_files: files('pc-bios/qemu-nsis.ico'),
180 include_directories: include_directories('.'))
181 elif targetos == 'darwin'
182 coref = dependency('appleframeworks', modules: 'CoreFoundation')
183 iokit = dependency('appleframeworks', modules: 'IOKit')
184 elif targetos == 'sunos'
185 socket = [cc.find_library('socket'),
186 cc.find_library('nsl'),
187 cc.find_library('resolv')]
188 elif targetos == 'haiku'
189 socket = [cc.find_library('posix_error_mapper'),
190 cc.find_library('network'),
191 cc.find_library('bsd')]
192 elif targetos == 'openbsd'
193 if not get_option('tcg').disabled() and target_dirs.length() > 0
194 # Disable OpenBSD W^X if available
195 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
200 if not get_option('kvm').disabled() and targetos == 'linux'
201 accelerators += 'CONFIG_KVM'
203 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
204 accelerators += 'CONFIG_XEN'
205 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
207 have_xen_pci_passthrough = false
209 if not get_option('whpx').disabled() and targetos == 'windows'
210 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
211 error('WHPX requires 64-bit host')
212 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
213 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
214 accelerators += 'CONFIG_WHPX'
217 if not get_option('hvf').disabled()
218 hvf = dependency('appleframeworks', modules: 'Hypervisor',
219 required: get_option('hvf'))
221 accelerators += 'CONFIG_HVF'
224 if not get_option('hax').disabled()
225 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
226 accelerators += 'CONFIG_HAX'
229 if not get_option('tcg').disabled()
230 if cpu not in supported_cpus
231 if 'CONFIG_TCG_INTERPRETER' in config_host
232 warning('Unsupported CPU @0@, will use TCG with TCI (experimental)'.format(cpu))
234 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
237 accelerators += 'CONFIG_TCG'
238 config_host += { 'CONFIG_TCG': 'y' }
241 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
242 error('KVM not available on this platform')
244 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
245 error('HVF not available on this platform')
247 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
248 error('WHPX not available on this platform')
250 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
251 if 'CONFIG_XEN' in accelerators
252 error('Xen PCI passthrough not available on this platform')
254 error('Xen PCI passthrough requested but Xen not enabled')
262 # The path to glib.h is added to all compilation commands. This was
263 # grandfathered in from the QEMU Makefiles.
264 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
265 native: false, language: ['c', 'cpp', 'objc'])
266 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
267 link_args: config_host['GLIB_LIBS'].split())
268 # override glib dep with the configure results (for subprojects)
269 meson.override_dependency('glib-2.0', glib)
272 if 'CONFIG_GIO' in config_host
273 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
274 link_args: config_host['GIO_LIBS'].split())
277 if 'CONFIG_TRACE_UST' in config_host
278 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
281 if 'CONFIG_TRACE_UST' in config_host
282 urcubp = declare_dependency(link_args: config_host['URCU_BP_LIBS'].split())
285 if 'CONFIG_GCRYPT' in config_host
286 gcrypt = declare_dependency(compile_args: config_host['GCRYPT_CFLAGS'].split(),
287 link_args: config_host['GCRYPT_LIBS'].split())
290 if 'CONFIG_NETTLE' in config_host
291 nettle = declare_dependency(compile_args: config_host['NETTLE_CFLAGS'].split(),
292 link_args: config_host['NETTLE_LIBS'].split())
295 if 'CONFIG_GNUTLS' in config_host
296 gnutls = declare_dependency(compile_args: config_host['GNUTLS_CFLAGS'].split(),
297 link_args: config_host['GNUTLS_LIBS'].split())
300 if have_system or have_tools
301 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
302 method: 'pkg-config', static: enable_static)
305 if 'CONFIG_AUTH_PAM' in config_host
306 pam = cc.find_library('pam')
308 libaio = cc.find_library('aio', required: false)
309 zlib = dependency('zlib', required: true, static: enable_static)
310 linux_io_uring = not_found
311 if 'CONFIG_LINUX_IO_URING' in config_host
312 linux_io_uring = declare_dependency(compile_args: config_host['LINUX_IO_URING_CFLAGS'].split(),
313 link_args: config_host['LINUX_IO_URING_LIBS'].split())
316 if 'CONFIG_LIBXML2' in config_host
317 libxml2 = declare_dependency(compile_args: config_host['LIBXML2_CFLAGS'].split(),
318 link_args: config_host['LIBXML2_LIBS'].split())
321 if not get_option('libnfs').auto() or have_block
322 libnfs = dependency('libnfs', version: '>=1.9.3',
323 required: get_option('libnfs'),
324 method: 'pkg-config', static: enable_static)
329 #include <sys/types.h>
330 #ifdef CONFIG_LIBATTR
331 #include <attr/xattr.h>
333 #include <sys/xattr.h>
335 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
338 have_old_libattr = false
339 if not get_option('attr').disabled()
340 if cc.links(libattr_test)
341 libattr = declare_dependency()
343 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
344 required: get_option('attr'),
345 static: enable_static)
346 if libattr.found() and not \
347 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
349 if get_option('attr').enabled()
350 error('could not link libattr')
352 warning('could not link libattr, disabling')
355 have_old_libattr = libattr.found()
360 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
361 if cocoa.found() and get_option('sdl').enabled()
362 error('Cocoa and SDL cannot be enabled at the same time')
364 if cocoa.found() and get_option('gtk').enabled()
365 error('Cocoa and GTK+ cannot be enabled at the same time')
369 if not get_option('seccomp').auto() or have_system or have_tools
370 seccomp = dependency('libseccomp', version: '>=2.3.0',
371 required: get_option('seccomp'),
372 method: 'pkg-config', static: enable_static)
375 libcap_ng = not_found
376 if not get_option('cap_ng').auto() or have_system or have_tools
377 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
378 required: get_option('cap_ng'),
379 static: enable_static)
381 if libcap_ng.found() and not cc.links('''
385 capng_capability_to_name(CAPNG_EFFECTIVE);
387 }''', dependencies: libcap_ng)
388 libcap_ng = not_found
389 if get_option('cap_ng').enabled()
390 error('could not link libcap-ng')
392 warning('could not link libcap-ng, disabling')
396 if get_option('xkbcommon').auto() and not have_system and not have_tools
397 xkbcommon = not_found
399 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
400 method: 'pkg-config', static: enable_static)
403 if config_host.has_key('CONFIG_VDE')
404 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
407 if 'CONFIG_LIBPULSE' in config_host
408 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
409 link_args: config_host['PULSE_LIBS'].split())
412 if 'CONFIG_ALSA' in config_host
413 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
414 link_args: config_host['ALSA_LIBS'].split())
417 if 'CONFIG_LIBJACK' in config_host
418 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
421 spice_headers = not_found
422 if 'CONFIG_SPICE' in config_host
423 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
424 link_args: config_host['SPICE_LIBS'].split())
425 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
427 rt = cc.find_library('rt', required: false)
429 if 'CONFIG_PLUGIN' in config_host
430 libdl = cc.find_library('dl', required: true)
433 if not get_option('libiscsi').auto() or have_block
434 libiscsi = dependency('libiscsi', version: '>=1.9.0',
435 required: get_option('libiscsi'),
436 method: 'pkg-config', static: enable_static)
439 if not get_option('zstd').auto() or have_block
440 zstd = dependency('libzstd', version: '>=1.4.0',
441 required: get_option('zstd'),
442 method: 'pkg-config', static: enable_static)
445 if 'CONFIG_GBM' in config_host
446 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
447 link_args: config_host['GBM_LIBS'].split())
450 if 'CONFIG_VIRGL' in config_host
451 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
452 link_args: config_host['VIRGL_LIBS'].split())
455 if not get_option('curl').auto() or have_block
456 curl = dependency('libcurl', version: '>=7.29.0',
457 method: 'pkg-config',
458 required: get_option('curl'),
459 static: enable_static)
462 if targetos == 'linux' and (have_system or have_tools)
463 libudev = dependency('libudev',
464 method: 'pkg-config',
465 required: get_option('libudev'),
466 static: enable_static)
469 mpathlibs = [libudev]
470 mpathpersist = not_found
471 mpathpersist_new_api = false
472 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
473 mpath_test_source_new = '''
475 #include <mpath_persist.h>
476 unsigned mpath_mx_alloc_len = 1024;
478 static struct config *multipath_conf;
479 extern struct udev *udev;
480 extern struct config *get_multipath_config(void);
481 extern void put_multipath_config(struct config *conf);
483 struct config *get_multipath_config(void) { return multipath_conf; }
484 void put_multipath_config(struct config *conf) { }
487 multipath_conf = mpath_lib_init();
490 mpath_test_source_old = '''
492 #include <mpath_persist.h>
493 unsigned mpath_mx_alloc_len = 1024;
496 struct udev *udev = udev_new();
497 mpath_lib_init(udev);
500 libmpathpersist = cc.find_library('mpathpersist',
501 required: get_option('mpath'),
502 static: enable_static)
503 if libmpathpersist.found()
504 mpathlibs += libmpathpersist
506 mpathlibs += cc.find_library('devmapper',
507 required: get_option('mpath'),
508 static: enable_static)
510 mpathlibs += cc.find_library('multipath',
511 required: get_option('mpath'),
512 static: enable_static)
513 foreach lib: mpathlibs
519 if mpathlibs.length() == 0
520 msg = 'Dependencies missing for libmpathpersist'
521 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
522 mpathpersist = declare_dependency(dependencies: mpathlibs)
523 mpathpersist_new_api = true
524 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
525 mpathpersist = declare_dependency(dependencies: mpathlibs)
527 msg = 'Cannot detect libmpathpersist API'
529 if not mpathpersist.found()
530 if get_option('mpath').enabled()
533 warning(msg + ', disabling')
541 if have_system and not get_option('curses').disabled()
548 setlocale(LC_ALL, "");
550 addwstr(L"wide chars\n");
552 add_wch(WACS_DEGREE);
556 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
557 foreach curses_dep : curses_dep_list
558 if not curses.found()
559 curses = dependency(curses_dep,
561 method: 'pkg-config',
562 static: enable_static)
565 msg = get_option('curses').enabled() ? 'curses library not found' : ''
566 curses_compile_args = ['-DNCURSES_WIDECHAR']
568 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
569 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
571 msg = 'curses package not usable'
575 if not curses.found()
576 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
577 if targetos != 'windows' and not has_curses_h
578 message('Trying with /usr/include/ncursesw')
579 curses_compile_args += ['-I/usr/include/ncursesw']
580 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
583 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
584 foreach curses_libname : curses_libname_list
585 libcurses = cc.find_library(curses_libname,
587 static: enable_static)
589 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
590 curses = declare_dependency(compile_args: curses_compile_args,
591 dependencies: [libcurses])
594 msg = 'curses library not usable'
600 if not get_option('iconv').disabled()
601 foreach link_args : [ ['-liconv'], [] ]
602 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
603 # We need to use libiconv if available because mixing libiconv's headers with
604 # the system libc does not work.
605 # However, without adding glib to the dependencies -L/usr/local/lib will not be
606 # included in the command line and libiconv will not be found.
610 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
611 return conv != (iconv_t) -1;
612 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
613 iconv = declare_dependency(link_args: link_args, dependencies: glib)
618 if curses.found() and not iconv.found()
619 if get_option('iconv').enabled()
620 error('iconv not available')
622 msg = 'iconv required for curses UI but not available'
625 if not curses.found() and msg != ''
626 if get_option('curses').enabled()
629 warning(msg + ', disabling')
635 if not get_option('brlapi').auto() or have_system
636 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
637 required: get_option('brlapi'),
638 static: enable_static)
639 if brlapi.found() and not cc.links('''
642 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
644 if get_option('brlapi').enabled()
645 error('could not link brlapi')
647 warning('could not link brlapi, disabling')
653 if not get_option('sdl').auto() or (have_system and not cocoa.found())
654 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
655 sdl_image = not_found
658 # work around 2.0.8 bug
659 sdl = declare_dependency(compile_args: '-Wno-undef',
661 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
662 method: 'pkg-config', static: enable_static)
664 if get_option('sdl_image').enabled()
665 error('sdl-image required, but SDL was @0@'.format(
666 get_option('sdl').disabled() ? 'disabled' : 'not found'))
668 sdl_image = not_found
672 if not get_option('rbd').auto() or have_block
673 librados = cc.find_library('rados', required: get_option('rbd'),
674 static: enable_static)
675 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
676 required: get_option('rbd'),
677 static: enable_static)
678 if librados.found() and librbd.found() and cc.links('''
680 #include <rbd/librbd.h>
683 rados_create(&cluster, NULL);
685 }''', dependencies: [librbd, librados])
686 rbd = declare_dependency(dependencies: [librbd, librados])
690 glusterfs = not_found
691 glusterfs_ftruncate_has_stat = false
692 glusterfs_iocb_has_stat = false
693 if not get_option('glusterfs').auto() or have_block
694 glusterfs = dependency('glusterfs-api', version: '>=3',
695 required: get_option('glusterfs'),
696 method: 'pkg-config', static: enable_static)
698 glusterfs_ftruncate_has_stat = cc.links('''
699 #include <glusterfs/api/glfs.h>
704 /* new glfs_ftruncate() passes two additional args */
705 return glfs_ftruncate(NULL, 0, NULL, NULL);
707 ''', dependencies: glusterfs)
708 glusterfs_iocb_has_stat = cc.links('''
709 #include <glusterfs/api/glfs.h>
711 /* new glfs_io_cbk() passes two additional glfs_stat structs */
713 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
719 glfs_io_cbk iocb = &glusterfs_iocb;
720 iocb(NULL, 0 , NULL, NULL, NULL);
723 ''', dependencies: glusterfs)
727 if 'CONFIG_LIBSSH' in config_host
728 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
729 link_args: config_host['LIBSSH_LIBS'].split())
732 if not get_option('bzip2').auto() or have_block
733 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
734 required: get_option('bzip2'),
735 static: enable_static)
736 if libbzip2.found() and not cc.links('''
738 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
740 if get_option('bzip2').enabled()
741 error('could not link libbzip2')
743 warning('could not link libbzip2, disabling')
749 if not get_option('lzfse').auto() or have_block
750 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
751 required: get_option('lzfse'),
752 static: enable_static)
754 if liblzfse.found() and not cc.links('''
756 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
758 if get_option('lzfse').enabled()
759 error('could not link liblzfse')
761 warning('could not link liblzfse, disabling')
766 if 'CONFIG_AUDIO_OSS' in config_host
767 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
770 if 'CONFIG_AUDIO_DSOUND' in config_host
771 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
773 coreaudio = not_found
774 if 'CONFIG_AUDIO_COREAUDIO' in config_host
775 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
778 if 'CONFIG_OPENGL' in config_host
779 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
780 link_args: config_host['OPENGL_LIBS'].split())
785 if not get_option('gtk').auto() or (have_system and not cocoa.found())
786 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
787 method: 'pkg-config',
788 required: get_option('gtk'),
789 static: enable_static)
791 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
792 method: 'pkg-config',
794 static: enable_static)
795 gtk = declare_dependency(dependencies: [gtk, gtkx11])
800 if 'CONFIG_VTE' in config_host
801 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
802 link_args: config_host['VTE_LIBS'].split())
805 if gtkx11.found() or 'lm32-softmmu' in target_dirs
806 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
807 static: enable_static)
813 if get_option('vnc').enabled()
814 vnc = declare_dependency() # dummy dependency
815 png = dependency('libpng', required: get_option('vnc_png'),
816 method: 'pkg-config', static: enable_static)
817 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
818 method: 'pkg-config', static: enable_static)
819 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
820 required: get_option('vnc_sasl'),
821 static: enable_static)
823 sasl = declare_dependency(dependencies: sasl,
824 compile_args: '-DSTRUCT_IOVEC_DEFINED')
829 if not get_option('snappy').auto() or have_system
830 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
831 required: get_option('snappy'),
832 static: enable_static)
834 if snappy.found() and not cc.links('''
835 #include <snappy-c.h>
836 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
838 if get_option('snappy').enabled()
839 error('could not link libsnappy')
841 warning('could not link libsnappy, disabling')
846 if not get_option('lzo').auto() or have_system
847 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
848 required: get_option('lzo'),
849 static: enable_static)
851 if lzo.found() and not cc.links('''
852 #include <lzo/lzo1x.h>
853 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
855 if get_option('lzo').enabled()
856 error('could not link liblzo2')
858 warning('could not link liblzo2, disabling')
863 if 'CONFIG_RDMA' in config_host
864 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
867 if 'CONFIG_NUMA' in config_host
868 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
871 if 'CONFIG_XEN_BACKEND' in config_host
872 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
873 link_args: config_host['XEN_LIBS'].split())
876 if 'CONFIG_SMARTCARD' in config_host
877 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
878 link_args: config_host['SMARTCARD_LIBS'].split())
882 u2f = dependency('u2f-emu', required: get_option('u2f'),
883 method: 'pkg-config',
884 static: enable_static)
887 if 'CONFIG_USB_REDIR' in config_host
888 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
889 link_args: config_host['USB_REDIR_LIBS'].split())
892 if 'CONFIG_USB_LIBUSB' in config_host
893 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
894 link_args: config_host['LIBUSB_LIBS'].split())
897 if 'CONFIG_LIBPMEM' in config_host
898 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
899 link_args: config_host['LIBPMEM_LIBS'].split())
901 libdaxctl = not_found
902 if 'CONFIG_LIBDAXCTL' in config_host
903 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
906 if 'CONFIG_TASN1' in config_host
907 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
908 link_args: config_host['TASN1_LIBS'].split())
910 keyutils = dependency('libkeyutils', required: false,
911 method: 'pkg-config', static: enable_static)
913 has_gettid = cc.has_function('gettid')
918 if get_option('malloc') == 'system'
920 not get_option('malloc_trim').disabled() and \
921 cc.links('''#include <malloc.h>
922 int main(void) { malloc_trim(0); return 0; }''')
924 has_malloc_trim = false
925 malloc = cc.find_library(get_option('malloc'), required: true)
927 if not has_malloc_trim and get_option('malloc_trim').enabled()
928 if get_option('malloc') == 'system'
929 error('malloc_trim not available on this platform.')
931 error('malloc_trim not available with non-libc memory allocator')
935 # Check whether the glibc provides statx()
941 #include <sys/stat.h>
943 struct statx statxbuf;
944 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
948 has_statx = cc.links(statx_test)
950 have_vhost_user_blk_server = (targetos == 'linux' and
951 'CONFIG_VHOST_USER' in config_host)
953 if get_option('vhost_user_blk_server').enabled()
954 if targetos != 'linux'
955 error('vhost_user_blk_server requires linux')
956 elif 'CONFIG_VHOST_USER' not in config_host
957 error('vhost_user_blk_server requires vhost-user support')
959 elif get_option('vhost_user_blk_server').disabled() or not have_system
960 have_vhost_user_blk_server = false
964 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
965 error('Cannot enable fuse-lseek while fuse is disabled')
968 fuse = dependency('fuse3', required: get_option('fuse'),
969 version: '>=3.1', method: 'pkg-config',
970 static: enable_static)
972 fuse_lseek = not_found
973 if not get_option('fuse_lseek').disabled()
974 if fuse.version().version_compare('>=3.8')
976 fuse_lseek = declare_dependency()
977 elif get_option('fuse_lseek').enabled()
979 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
981 error('fuse-lseek requires libfuse, which was not found')
988 # Check for dependency on LTO
989 if not get_option('b_lto')
990 error('Selected Control-Flow Integrity but LTO is disabled')
992 if config_host.has_key('CONFIG_MODULES')
993 error('Selected Control-Flow Integrity is not compatible with modules')
995 # Check for cfi flags. CFI requires LTO so we can't use
996 # get_supported_arguments, but need a more complex "compiles" which allows
998 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
999 args: ['-flto', '-fsanitize=cfi-icall'] )
1000 cfi_flags += '-fsanitize=cfi-icall'
1002 error('-fsanitize=cfi-icall is not supported by the compiler')
1004 if cc.compiles('int main () { return 0; }',
1005 name: '-fsanitize-cfi-icall-generalize-pointers',
1006 args: ['-flto', '-fsanitize=cfi-icall',
1007 '-fsanitize-cfi-icall-generalize-pointers'] )
1008 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1010 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1012 if get_option('cfi_debug')
1013 if cc.compiles('int main () { return 0; }',
1014 name: '-fno-sanitize-trap=cfi-icall',
1015 args: ['-flto', '-fsanitize=cfi-icall',
1016 '-fno-sanitize-trap=cfi-icall'] )
1017 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1019 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1022 add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1023 add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1030 have_virtfs = (targetos == 'linux' and
1035 if get_option('virtfs').enabled()
1037 if targetos != 'linux'
1038 error('virtio-9p (virtfs) requires Linux')
1039 elif not libcap_ng.found() or not libattr.found()
1040 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1041 elif not have_system
1042 error('virtio-9p (virtfs) needs system emulation support')
1045 elif get_option('virtfs').disabled()
1049 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1050 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1051 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1052 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1053 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1054 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1055 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1056 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1057 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1058 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1059 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1060 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1062 config_host_data.set('CONFIG_ATTR', libattr.found())
1063 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1064 config_host_data.set('CONFIG_COCOA', cocoa.found())
1065 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1066 config_host_data.set('CONFIG_LZO', lzo.found())
1067 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1068 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1069 config_host_data.set('CONFIG_CURL', curl.found())
1070 config_host_data.set('CONFIG_CURSES', curses.found())
1071 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1072 if glusterfs.found()
1073 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1074 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1075 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1076 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1077 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1078 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1080 config_host_data.set('CONFIG_GTK', gtk.found())
1081 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1082 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1083 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1084 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1085 config_host_data.set('CONFIG_RBD', rbd.found())
1086 config_host_data.set('CONFIG_SDL', sdl.found())
1087 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1088 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1089 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1090 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1091 config_host_data.set('CONFIG_VNC', vnc.found())
1092 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1093 config_host_data.set('CONFIG_VNC_PNG', png.found())
1094 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1095 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1096 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1097 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1098 config_host_data.set('CONFIG_GETTID', has_gettid)
1099 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1100 config_host_data.set('CONFIG_STATX', has_statx)
1101 config_host_data.set('CONFIG_ZSTD', zstd.found())
1102 config_host_data.set('CONFIG_FUSE', fuse.found())
1103 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1104 config_host_data.set('CONFIG_X11', x11.found())
1105 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1106 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1107 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1108 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1109 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1111 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1112 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1113 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1114 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1115 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1117 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1118 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1119 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1120 foreach k, v: config_host
1121 if ignored.contains(k)
1123 elif arrays.contains(k)
1125 v = '"' + '", "'.join(v.split()) + '", '
1127 config_host_data.set(k, v)
1129 config_host_data.set('HOST_' + v.to_upper(), 1)
1130 elif strings.contains(k)
1131 if not k.startswith('CONFIG_')
1132 k = 'CONFIG_' + k.to_upper()
1134 config_host_data.set_quoted(k, v)
1135 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1136 config_host_data.set(k, v == 'y' ? 1 : v)
1140 ########################
1141 # Target configuration #
1142 ########################
1144 minikconf = find_program('scripts/minikconf.py')
1146 config_all_devices = {}
1147 config_all_disas = {}
1148 config_devices_mak_list = []
1149 config_devices_h = {}
1150 config_target_h = {}
1151 config_target_mak = {}
1154 'alpha' : ['CONFIG_ALPHA_DIS'],
1155 'arm' : ['CONFIG_ARM_DIS'],
1156 'avr' : ['CONFIG_AVR_DIS'],
1157 'cris' : ['CONFIG_CRIS_DIS'],
1158 'hppa' : ['CONFIG_HPPA_DIS'],
1159 'i386' : ['CONFIG_I386_DIS'],
1160 'x86_64' : ['CONFIG_I386_DIS'],
1161 'x32' : ['CONFIG_I386_DIS'],
1162 'lm32' : ['CONFIG_LM32_DIS'],
1163 'm68k' : ['CONFIG_M68K_DIS'],
1164 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1165 'mips' : ['CONFIG_MIPS_DIS'],
1166 'moxie' : ['CONFIG_MOXIE_DIS'],
1167 'nios2' : ['CONFIG_NIOS2_DIS'],
1168 'or1k' : ['CONFIG_OPENRISC_DIS'],
1169 'ppc' : ['CONFIG_PPC_DIS'],
1170 'riscv' : ['CONFIG_RISCV_DIS'],
1171 'rx' : ['CONFIG_RX_DIS'],
1172 's390' : ['CONFIG_S390_DIS'],
1173 'sh4' : ['CONFIG_SH4_DIS'],
1174 'sparc' : ['CONFIG_SPARC_DIS'],
1175 'xtensa' : ['CONFIG_XTENSA_DIS'],
1177 if link_language == 'cpp'
1179 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1180 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1181 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1186 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1187 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1188 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1189 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1190 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1191 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1192 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1193 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1194 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1195 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1196 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1198 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1200 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1201 actual_target_dirs = []
1203 foreach target : target_dirs
1204 config_target = { 'TARGET_NAME': target.split('-')[0] }
1205 if target.endswith('linux-user')
1206 if targetos != 'linux'
1210 error('Target @0@ is only available on a Linux host'.format(target))
1212 config_target += { 'CONFIG_LINUX_USER': 'y' }
1213 elif target.endswith('bsd-user')
1214 if 'CONFIG_BSD' not in config_host
1218 error('Target @0@ is only available on a BSD host'.format(target))
1220 config_target += { 'CONFIG_BSD_USER': 'y' }
1221 elif target.endswith('softmmu')
1222 config_target += { 'CONFIG_SOFTMMU': 'y' }
1224 if target.endswith('-user')
1226 'CONFIG_USER_ONLY': 'y',
1227 'CONFIG_QEMU_INTERP_PREFIX':
1228 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1233 foreach sym: accelerators
1234 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1235 config_target += { sym: 'y' }
1236 config_all += { sym: 'y' }
1237 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1238 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1240 accel_kconfig += [ sym + '=y' ]
1243 if accel_kconfig.length() == 0
1247 error('No accelerator available for target @0@'.format(target))
1250 actual_target_dirs += target
1251 config_target += keyval.load('default-configs/targets' / target + '.mak')
1252 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1254 if 'TARGET_NEED_FDT' in config_target
1255 fdt_required += target
1259 if 'TARGET_BASE_ARCH' not in config_target
1260 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1262 if 'TARGET_ABI_DIR' not in config_target
1263 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1266 foreach k, v: disassemblers
1267 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1269 config_target += { sym: 'y' }
1270 config_all_disas += { sym: 'y' }
1275 config_target_data = configuration_data()
1276 foreach k, v: config_target
1277 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1279 elif ignored.contains(k)
1281 elif k == 'TARGET_BASE_ARCH'
1282 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1283 # not used to select files from sourcesets.
1284 config_target_data.set('TARGET_' + v.to_upper(), 1)
1285 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1286 config_target_data.set_quoted(k, v)
1288 config_target_data.set(k, 1)
1290 config_target_data.set(k, v)
1293 config_target_h += {target: configure_file(output: target + '-config-target.h',
1294 configuration: config_target_data)}
1296 if target.endswith('-softmmu')
1297 config_devices_mak = target + '-config-devices.mak'
1298 config_devices_mak = configure_file(
1299 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1300 output: config_devices_mak,
1301 depfile: config_devices_mak + '.d',
1303 command: [minikconf,
1304 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1305 config_devices_mak, '@DEPFILE@', '@INPUT@',
1306 host_kconfig, accel_kconfig])
1308 config_devices_data = configuration_data()
1309 config_devices = keyval.load(config_devices_mak)
1310 foreach k, v: config_devices
1311 config_devices_data.set(k, 1)
1313 config_devices_mak_list += config_devices_mak
1314 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1315 configuration: config_devices_data)}
1316 config_target += config_devices
1317 config_all_devices += config_devices
1319 config_target_mak += {target: config_target}
1321 target_dirs = actual_target_dirs
1323 # This configuration is used to build files that are shared by
1324 # multiple binaries, and then extracted out of the "common"
1325 # static_library target.
1327 # We do not use all_sources()/all_dependencies(), because it would
1328 # build literally all source files, including devices only used by
1329 # targets that are not built for this compilation. The CONFIG_ALL
1330 # pseudo symbol replaces it.
1332 config_all += config_all_devices
1333 config_all += config_host
1334 config_all += config_all_disas
1336 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1337 'CONFIG_SOFTMMU': have_system,
1338 'CONFIG_USER_ONLY': have_user,
1346 capstone = not_found
1347 capstone_opt = get_option('capstone')
1348 if capstone_opt in ['enabled', 'auto', 'system']
1349 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1350 capstone = dependency('capstone', version: '>=4.0',
1351 static: enable_static, method: 'pkg-config',
1352 required: capstone_opt == 'system' or
1353 capstone_opt == 'enabled' and not have_internal)
1355 capstone_opt = 'system'
1357 capstone_opt = 'internal'
1359 capstone_opt = 'disabled'
1362 if capstone_opt == 'internal'
1363 capstone_data = configuration_data()
1364 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1366 capstone_files = files(
1368 'capstone/MCInst.c',
1369 'capstone/MCInstrDesc.c',
1370 'capstone/MCRegisterInfo.c',
1371 'capstone/SStream.c',
1375 if 'CONFIG_ARM_DIS' in config_all_disas
1376 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1377 capstone_files += files(
1378 'capstone/arch/ARM/ARMDisassembler.c',
1379 'capstone/arch/ARM/ARMInstPrinter.c',
1380 'capstone/arch/ARM/ARMMapping.c',
1381 'capstone/arch/ARM/ARMModule.c'
1385 # FIXME: This config entry currently depends on a c++ compiler.
1386 # Which is needed for building libvixl, but not for capstone.
1387 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1388 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1389 capstone_files += files(
1390 'capstone/arch/AArch64/AArch64BaseInfo.c',
1391 'capstone/arch/AArch64/AArch64Disassembler.c',
1392 'capstone/arch/AArch64/AArch64InstPrinter.c',
1393 'capstone/arch/AArch64/AArch64Mapping.c',
1394 'capstone/arch/AArch64/AArch64Module.c'
1398 if 'CONFIG_PPC_DIS' in config_all_disas
1399 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1400 capstone_files += files(
1401 'capstone/arch/PowerPC/PPCDisassembler.c',
1402 'capstone/arch/PowerPC/PPCInstPrinter.c',
1403 'capstone/arch/PowerPC/PPCMapping.c',
1404 'capstone/arch/PowerPC/PPCModule.c'
1408 if 'CONFIG_S390_DIS' in config_all_disas
1409 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1410 capstone_files += files(
1411 'capstone/arch/SystemZ/SystemZDisassembler.c',
1412 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1413 'capstone/arch/SystemZ/SystemZMapping.c',
1414 'capstone/arch/SystemZ/SystemZModule.c',
1415 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1419 if 'CONFIG_I386_DIS' in config_all_disas
1420 capstone_data.set('CAPSTONE_HAS_X86', 1)
1421 capstone_files += files(
1422 'capstone/arch/X86/X86Disassembler.c',
1423 'capstone/arch/X86/X86DisassemblerDecoder.c',
1424 'capstone/arch/X86/X86ATTInstPrinter.c',
1425 'capstone/arch/X86/X86IntelInstPrinter.c',
1426 'capstone/arch/X86/X86InstPrinterCommon.c',
1427 'capstone/arch/X86/X86Mapping.c',
1428 'capstone/arch/X86/X86Module.c'
1432 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1435 # FIXME: There does not seem to be a way to completely replace the c_args
1436 # that come from add_project_arguments() -- we can only add to them.
1437 # So: disable all warnings with a big hammer.
1440 # Include all configuration defines via a header file, which will wind up
1441 # as a dependency on the object file, and thus changes here will result
1443 '-include', 'capstone-defs.h'
1446 libcapstone = static_library('capstone',
1447 sources: capstone_files,
1448 c_args: capstone_cargs,
1449 include_directories: 'capstone/include')
1450 capstone = declare_dependency(link_with: libcapstone,
1451 include_directories: 'capstone/include/capstone')
1455 slirp_opt = 'disabled'
1457 slirp_opt = get_option('slirp')
1458 if slirp_opt in ['enabled', 'auto', 'system']
1459 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1460 slirp = dependency('slirp', static: enable_static,
1461 method: 'pkg-config',
1462 required: slirp_opt == 'system' or
1463 slirp_opt == 'enabled' and not have_internal)
1465 slirp_opt = 'system'
1467 slirp_opt = 'internal'
1469 slirp_opt = 'disabled'
1472 if slirp_opt == 'internal'
1474 if targetos == 'windows'
1475 slirp_deps = cc.find_library('iphlpapi')
1477 slirp_conf = configuration_data()
1478 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1479 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1480 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1481 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1482 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1484 'slirp/src/arp_table.c',
1485 'slirp/src/bootp.c',
1486 'slirp/src/cksum.c',
1487 'slirp/src/dhcpv6.c',
1488 'slirp/src/dnssearch.c',
1490 'slirp/src/ip6_icmp.c',
1491 'slirp/src/ip6_input.c',
1492 'slirp/src/ip6_output.c',
1493 'slirp/src/ip_icmp.c',
1494 'slirp/src/ip_input.c',
1495 'slirp/src/ip_output.c',
1499 'slirp/src/ndp_table.c',
1501 'slirp/src/slirp.c',
1502 'slirp/src/socket.c',
1503 'slirp/src/state.c',
1504 'slirp/src/stream.c',
1505 'slirp/src/tcp_input.c',
1506 'slirp/src/tcp_output.c',
1507 'slirp/src/tcp_subr.c',
1508 'slirp/src/tcp_timer.c',
1513 'slirp/src/version.c',
1514 'slirp/src/vmstate.c',
1518 input : 'slirp/src/libslirp-version.h.in',
1519 output : 'libslirp-version.h',
1520 configuration: slirp_conf)
1522 slirp_inc = include_directories('slirp', 'slirp/src')
1523 libslirp = static_library('slirp',
1524 sources: slirp_files,
1525 c_args: slirp_cargs,
1526 include_directories: slirp_inc)
1527 slirp = declare_dependency(link_with: libslirp,
1528 dependencies: slirp_deps,
1529 include_directories: slirp_inc)
1534 fdt_opt = get_option('fdt')
1536 if fdt_opt in ['enabled', 'auto', 'system']
1537 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1538 fdt = cc.find_library('fdt', static: enable_static,
1539 required: fdt_opt == 'system' or
1540 fdt_opt == 'enabled' and not have_internal)
1541 if fdt.found() and cc.links('''
1543 #include <libfdt_env.h>
1544 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1548 fdt_opt = 'internal'
1550 fdt_opt = 'disabled'
1553 if fdt_opt == 'internal'
1556 'dtc/libfdt/fdt_ro.c',
1557 'dtc/libfdt/fdt_wip.c',
1558 'dtc/libfdt/fdt_sw.c',
1559 'dtc/libfdt/fdt_rw.c',
1560 'dtc/libfdt/fdt_strerror.c',
1561 'dtc/libfdt/fdt_empty_tree.c',
1562 'dtc/libfdt/fdt_addresses.c',
1563 'dtc/libfdt/fdt_overlay.c',
1564 'dtc/libfdt/fdt_check.c',
1567 fdt_inc = include_directories('dtc/libfdt')
1568 libfdt = static_library('fdt',
1570 include_directories: fdt_inc)
1571 fdt = declare_dependency(link_with: libfdt,
1572 include_directories: fdt_inc)
1575 if not fdt.found() and fdt_required.length() > 0
1576 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1579 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1580 config_host_data.set('CONFIG_FDT', fdt.found())
1581 config_host_data.set('CONFIG_SLIRP', slirp.found())
1583 #####################
1584 # Generated sources #
1585 #####################
1587 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1589 hxtool = find_program('scripts/hxtool')
1590 shaderinclude = find_program('scripts/shaderinclude.pl')
1591 qapi_gen = find_program('scripts/qapi-gen.py')
1592 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1593 meson.source_root() / 'scripts/qapi/commands.py',
1594 meson.source_root() / 'scripts/qapi/common.py',
1595 meson.source_root() / 'scripts/qapi/error.py',
1596 meson.source_root() / 'scripts/qapi/events.py',
1597 meson.source_root() / 'scripts/qapi/expr.py',
1598 meson.source_root() / 'scripts/qapi/gen.py',
1599 meson.source_root() / 'scripts/qapi/introspect.py',
1600 meson.source_root() / 'scripts/qapi/parser.py',
1601 meson.source_root() / 'scripts/qapi/schema.py',
1602 meson.source_root() / 'scripts/qapi/source.py',
1603 meson.source_root() / 'scripts/qapi/types.py',
1604 meson.source_root() / 'scripts/qapi/visit.py',
1605 meson.source_root() / 'scripts/qapi/common.py',
1606 meson.source_root() / 'scripts/qapi-gen.py'
1610 python, files('scripts/tracetool.py'),
1611 '--backend=' + config_host['TRACE_BACKENDS']
1614 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1615 meson.current_source_dir(),
1616 config_host['PKGVERSION'], meson.project_version()]
1617 qemu_version = custom_target('qemu-version.h',
1618 output: 'qemu-version.h',
1619 command: qemu_version_cmd,
1621 build_by_default: true,
1622 build_always_stale: true)
1623 genh += qemu_version
1627 ['qemu-options.hx', 'qemu-options.def'],
1628 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1632 ['hmp-commands.hx', 'hmp-commands.h'],
1633 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1636 foreach d : hx_headers
1637 hxdep += custom_target(d[1],
1641 build_by_default: true, # to be removed when added to a target
1642 command: [hxtool, '-h', '@INPUT0@'])
1650 authz_ss = ss.source_set()
1651 blockdev_ss = ss.source_set()
1652 block_ss = ss.source_set()
1653 bsd_user_ss = ss.source_set()
1654 chardev_ss = ss.source_set()
1655 common_ss = ss.source_set()
1656 crypto_ss = ss.source_set()
1657 io_ss = ss.source_set()
1658 linux_user_ss = ss.source_set()
1659 qmp_ss = ss.source_set()
1660 qom_ss = ss.source_set()
1661 softmmu_ss = ss.source_set()
1662 specific_fuzz_ss = ss.source_set()
1663 specific_ss = ss.source_set()
1664 stub_ss = ss.source_set()
1665 trace_ss = ss.source_set()
1666 user_ss = ss.source_set()
1667 util_ss = ss.source_set()
1672 target_softmmu_arch = {}
1678 # TODO: add each directory to the subdirs from its own meson.build, once
1680 trace_events_subdirs = [
1687 trace_events_subdirs += [ 'linux-user' ]
1690 trace_events_subdirs += [
1699 trace_events_subdirs += [
1711 'hw/block/dataplane',
1757 trace_events_subdirs += [
1773 vhost_user = not_found
1774 if 'CONFIG_VHOST_USER' in config_host
1775 libvhost_user = subproject('libvhost-user')
1776 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1791 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1792 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1795 stub_ss = stub_ss.apply(config_all, strict: false)
1797 util_ss.add_all(trace_ss)
1798 util_ss = util_ss.apply(config_all, strict: false)
1799 libqemuutil = static_library('qemuutil',
1800 sources: util_ss.sources() + stub_ss.sources() + genh,
1801 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1802 qemuutil = declare_dependency(link_with: libqemuutil,
1803 sources: genh + version_res)
1805 decodetree = generator(find_program('scripts/decodetree.py'),
1807 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1813 subdir('libdecnumber')
1823 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1829 blockdev_ss.add(files(
1836 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1837 # os-win32.c does not
1838 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1839 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1841 common_ss.add(files('cpus-common.c'))
1845 common_ss.add(capstone)
1846 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1847 specific_ss.add(files('exec-vary.c'))
1848 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1852 'tcg/tcg-op-gvec.c',
1857 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1869 subdir('linux-user')
1871 bsd_user_ss.add(files('gdbstub.c'))
1872 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1874 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1875 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1877 # needed for fuzzing binaries
1878 subdir('tests/qtest/libqos')
1879 subdir('tests/qtest/fuzz')
1881 ########################
1882 # Library dependencies #
1883 ########################
1887 foreach d, list : modules
1888 foreach m, module_ss : list
1889 if enable_modules and targetos != 'windows'
1890 module_ss = module_ss.apply(config_all, strict: false)
1891 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1892 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1900 block_ss.add_all(module_ss)
1902 softmmu_ss.add_all(module_ss)
1908 nm = find_program('nm')
1909 undefsym = find_program('scripts/undefsym.py')
1910 block_syms = custom_target('block.syms', output: 'block.syms',
1911 input: [libqemuutil, block_mods],
1913 command: [undefsym, nm, '@INPUT@'])
1914 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1915 input: [libqemuutil, softmmu_mods],
1917 command: [undefsym, nm, '@INPUT@'])
1919 qom_ss = qom_ss.apply(config_host, strict: false)
1920 libqom = static_library('qom', qom_ss.sources() + genh,
1921 dependencies: [qom_ss.dependencies()],
1924 qom = declare_dependency(link_whole: libqom)
1926 authz_ss = authz_ss.apply(config_host, strict: false)
1927 libauthz = static_library('authz', authz_ss.sources() + genh,
1928 dependencies: [authz_ss.dependencies()],
1930 build_by_default: false)
1932 authz = declare_dependency(link_whole: libauthz,
1935 crypto_ss = crypto_ss.apply(config_host, strict: false)
1936 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1937 dependencies: [crypto_ss.dependencies()],
1939 build_by_default: false)
1941 crypto = declare_dependency(link_whole: libcrypto,
1942 dependencies: [authz, qom])
1944 io_ss = io_ss.apply(config_host, strict: false)
1945 libio = static_library('io', io_ss.sources() + genh,
1946 dependencies: [io_ss.dependencies()],
1947 link_with: libqemuutil,
1949 build_by_default: false)
1951 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1953 libmigration = static_library('migration', sources: migration_files + genh,
1955 build_by_default: false)
1956 migration = declare_dependency(link_with: libmigration,
1957 dependencies: [zlib, qom, io])
1958 softmmu_ss.add(migration)
1960 block_ss = block_ss.apply(config_host, strict: false)
1961 libblock = static_library('block', block_ss.sources() + genh,
1962 dependencies: block_ss.dependencies(),
1963 link_depends: block_syms,
1965 build_by_default: false)
1967 block = declare_dependency(link_whole: [libblock],
1968 link_args: '@block.syms',
1969 dependencies: [crypto, io])
1971 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1972 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1973 dependencies: blockdev_ss.dependencies(),
1975 build_by_default: false)
1977 blockdev = declare_dependency(link_whole: [libblockdev],
1978 dependencies: [block])
1980 qmp_ss = qmp_ss.apply(config_host, strict: false)
1981 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1982 dependencies: qmp_ss.dependencies(),
1984 build_by_default: false)
1986 qmp = declare_dependency(link_whole: [libqmp])
1988 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1990 dependencies: [gnutls],
1991 build_by_default: false)
1993 chardev = declare_dependency(link_whole: libchardev)
1995 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1997 build_by_default: false)
1998 hwcore = declare_dependency(link_whole: libhwcore)
1999 common_ss.add(hwcore)
2005 foreach m : block_mods + softmmu_mods
2006 shared_module(m.name(),
2010 install_dir: qemu_moddir)
2013 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2014 common_ss.add(qom, qemuutil)
2016 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2017 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2019 common_all = common_ss.apply(config_all, strict: false)
2020 common_all = static_library('common',
2021 build_by_default: false,
2022 sources: common_all.sources() + genh,
2023 dependencies: common_all.dependencies(),
2026 feature_to_c = find_program('scripts/feature_to_c.sh')
2029 foreach target : target_dirs
2030 config_target = config_target_mak[target]
2031 target_name = config_target['TARGET_NAME']
2032 arch = config_target['TARGET_BASE_ARCH']
2033 arch_srcs = [config_target_h[target]]
2035 c_args = ['-DNEED_CPU_H',
2038 link_args = emulator_link_args
2040 config_target += config_host
2041 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2042 if targetos == 'linux'
2043 target_inc += include_directories('linux-headers', is_system: true)
2045 if target.endswith('-softmmu')
2046 qemu_target_name = 'qemu-system-' + target_name
2047 target_type='system'
2048 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2049 arch_srcs += t.sources()
2050 arch_deps += t.dependencies()
2052 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2053 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2054 arch_srcs += hw.sources()
2055 arch_deps += hw.dependencies()
2057 arch_srcs += config_devices_h[target]
2058 link_args += ['@block.syms', '@qemu.syms']
2060 abi = config_target['TARGET_ABI_DIR']
2062 qemu_target_name = 'qemu-' + target_name
2063 if 'CONFIG_LINUX_USER' in config_target
2064 base_dir = 'linux-user'
2065 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2067 base_dir = 'bsd-user'
2068 target_inc += include_directories('bsd-user/freebsd')
2070 target_inc += include_directories(
2074 if 'CONFIG_LINUX_USER' in config_target
2075 dir = base_dir / abi
2076 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2077 if config_target.has_key('TARGET_SYSTBL_ABI')
2079 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2080 extra_args : config_target['TARGET_SYSTBL_ABI'])
2085 if 'TARGET_XML_FILES' in config_target
2086 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2087 output: target + '-gdbstub-xml.c',
2088 input: files(config_target['TARGET_XML_FILES'].split()),
2089 command: [feature_to_c, '@INPUT@'],
2091 arch_srcs += gdbstub_xml
2094 t = target_arch[arch].apply(config_target, strict: false)
2095 arch_srcs += t.sources()
2096 arch_deps += t.dependencies()
2098 target_common = common_ss.apply(config_target, strict: false)
2099 objects = common_all.extract_objects(target_common.sources())
2100 deps = target_common.dependencies()
2102 target_specific = specific_ss.apply(config_target, strict: false)
2103 arch_srcs += target_specific.sources()
2104 arch_deps += target_specific.dependencies()
2106 lib = static_library('qemu-' + target,
2107 sources: arch_srcs + genh,
2108 dependencies: arch_deps,
2110 include_directories: target_inc,
2112 build_by_default: false,
2115 if target.endswith('-softmmu')
2117 'name': 'qemu-system-' + target_name,
2119 'sources': files('softmmu/main.c'),
2122 if targetos == 'windows' and (sdl.found() or gtk.found())
2124 'name': 'qemu-system-' + target_name + 'w',
2126 'sources': files('softmmu/main.c'),
2130 if config_host.has_key('CONFIG_FUZZ')
2131 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2133 'name': 'qemu-fuzz-' + target_name,
2135 'sources': specific_fuzz.sources(),
2136 'dependencies': specific_fuzz.dependencies(),
2141 'name': 'qemu-' + target_name,
2148 emulators += {exe['name']:
2149 executable(exe['name'], exe['sources'],
2152 dependencies: arch_deps + deps + exe['dependencies'],
2153 objects: lib.extract_all_objects(recursive: true),
2154 link_language: link_language,
2155 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2156 link_args: link_args,
2157 gui_app: exe['gui'])
2160 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2162 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2163 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2164 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2165 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2167 custom_target(exe['name'] + stp['ext'],
2168 input: trace_events_all,
2169 output: exe['name'] + stp['ext'],
2170 install: stp['install'],
2171 install_dir: get_option('datadir') / 'systemtap/tapset',
2173 tracetool, '--group=all', '--format=' + stp['fmt'],
2174 '--binary=' + stp['bin'],
2175 '--target-name=' + target_name,
2176 '--target-type=' + target_type,
2177 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2178 '@INPUT@', '@OUTPUT@'
2185 # Other build targets
2187 if 'CONFIG_PLUGIN' in config_host
2188 install_headers('include/qemu/qemu-plugin.h')
2191 if 'CONFIG_GUEST_AGENT' in config_host
2195 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2196 # when we don't build tools or system
2197 if xkbcommon.found()
2198 # used for the update-keymaps target, so include rules even if !have_tools
2199 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2200 dependencies: [qemuutil, xkbcommon], install: have_tools)
2204 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2205 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2206 qemu_io = executable('qemu-io', files('qemu-io.c'),
2207 dependencies: [block, qemuutil], install: true)
2208 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2209 dependencies: [blockdev, qemuutil, gnutls], install: true)
2211 subdir('storage-daemon')
2212 subdir('contrib/rdmacm-mux')
2213 subdir('contrib/elf2dmp')
2215 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2216 dependencies: qemuutil,
2219 if 'CONFIG_VHOST_USER' in config_host
2220 subdir('contrib/vhost-user-blk')
2221 subdir('contrib/vhost-user-gpu')
2222 subdir('contrib/vhost-user-input')
2223 subdir('contrib/vhost-user-scsi')
2226 if targetos == 'linux'
2227 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2228 dependencies: [qemuutil, libcap_ng],
2230 install_dir: get_option('libexecdir'))
2232 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2233 dependencies: [authz, crypto, io, qom, qemuutil,
2234 libcap_ng, mpathpersist],
2238 if 'CONFIG_IVSHMEM' in config_host
2239 subdir('contrib/ivshmem-client')
2240 subdir('contrib/ivshmem-server')
2253 if host_machine.system() == 'windows'
2255 find_program('scripts/nsis.py'),
2257 get_option('prefix'),
2258 meson.current_source_dir(),
2261 '-DDISPLAYVERSION=' + meson.project_version(),
2264 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2267 nsis_cmd += '-DCONFIG_GTK=y'
2270 nsis = custom_target('nsis',
2271 output: 'qemu-setup-' + meson.project_version() + '.exe',
2272 input: files('qemu.nsi'),
2273 build_always_stale: true,
2274 command: nsis_cmd + ['@INPUT@'])
2275 alias_target('installer', nsis)
2278 #########################
2279 # Configuration summary #
2280 #########################
2283 summary_info += {'Install prefix': get_option('prefix')}
2284 summary_info += {'BIOS directory': qemu_datadir}
2285 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2286 summary_info += {'binary directory': get_option('bindir')}
2287 summary_info += {'library directory': get_option('libdir')}
2288 summary_info += {'module directory': qemu_moddir}
2289 summary_info += {'libexec directory': get_option('libexecdir')}
2290 summary_info += {'include directory': get_option('includedir')}
2291 summary_info += {'config directory': get_option('sysconfdir')}
2292 if targetos != 'windows'
2293 summary_info += {'local state directory': get_option('localstatedir')}
2294 summary_info += {'Manual directory': get_option('mandir')}
2296 summary_info += {'local state directory': 'queried at runtime'}
2298 summary_info += {'Doc directory': get_option('docdir')}
2299 summary_info += {'Build directory': meson.current_build_dir()}
2300 summary_info += {'Source path': meson.current_source_dir()}
2301 summary_info += {'GIT binary': config_host['GIT']}
2302 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2303 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2304 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2305 if link_language == 'cpp'
2306 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2308 summary_info += {'C++ compiler': false}
2310 if targetos == 'darwin'
2311 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2313 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2314 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2315 + ['-O' + get_option('optimization')]
2316 + (get_option('debug') ? ['-g'] : []))}
2317 if link_language == 'cpp'
2318 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2319 + ['-O' + get_option('optimization')]
2320 + (get_option('debug') ? ['-g'] : []))}
2322 link_args = get_option(link_language + '_link_args')
2323 if link_args.length() > 0
2324 summary_info += {'LDFLAGS': ' '.join(link_args)}
2326 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2327 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2328 summary_info += {'make': config_host['MAKE']}
2329 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2330 summary_info += {'sphinx-build': sphinx_build.found()}
2331 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2332 # TODO: add back version
2333 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2334 if slirp_opt != 'disabled'
2335 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2337 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2338 if config_host.has_key('CONFIG_MODULES')
2339 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2341 summary_info += {'host CPU': cpu}
2342 summary_info += {'host endianness': build_machine.endian()}
2343 summary_info += {'target list': ' '.join(target_dirs)}
2344 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2345 summary_info += {'sparse enabled': sparse.found()}
2346 summary_info += {'strip binaries': get_option('strip')}
2347 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2348 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2349 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2350 if targetos == 'darwin'
2351 summary_info += {'Cocoa support': cocoa.found()}
2353 # TODO: add back version
2354 summary_info += {'SDL support': sdl.found()}
2355 summary_info += {'SDL image support': sdl_image.found()}
2356 # TODO: add back version
2357 summary_info += {'GTK support': gtk.found()}
2358 summary_info += {'pixman': pixman.found()}
2359 # TODO: add back version
2360 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2361 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2362 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2363 # TODO: add back version
2364 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2365 if config_host.has_key('CONFIG_GCRYPT')
2366 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2367 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2369 # TODO: add back version
2370 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2371 if config_host.has_key('CONFIG_NETTLE')
2372 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2374 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2375 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2376 summary_info += {'iconv support': iconv.found()}
2377 summary_info += {'curses support': curses.found()}
2378 # TODO: add back version
2379 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2380 summary_info += {'curl support': curl.found()}
2381 summary_info += {'mingw32 support': targetos == 'windows'}
2382 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2383 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2384 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2385 summary_info += {'VirtFS support': have_virtfs}
2386 summary_info += {'build virtiofs daemon': have_virtiofsd}
2387 summary_info += {'Multipath support': mpathpersist.found()}
2388 summary_info += {'VNC support': vnc.found()}
2390 summary_info += {'VNC SASL support': sasl.found()}
2391 summary_info += {'VNC JPEG support': jpeg.found()}
2392 summary_info += {'VNC PNG support': png.found()}
2394 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2395 if config_host.has_key('CONFIG_XEN_BACKEND')
2396 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2398 summary_info += {'brlapi support': brlapi.found()}
2399 summary_info += {'Documentation': build_docs}
2400 summary_info += {'PIE': get_option('b_pie')}
2401 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2402 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2403 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2404 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2405 summary_info += {'ATTR/XATTR support': libattr.found()}
2406 summary_info += {'Install blobs': get_option('install_blobs')}
2407 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2408 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2409 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2410 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2411 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2412 if config_all.has_key('CONFIG_TCG')
2413 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2414 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
2416 summary_info += {'malloc trim support': has_malloc_trim}
2417 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2418 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2419 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2420 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2421 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2422 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2423 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2424 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2425 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2426 summary_info += {'libcap-ng support': libcap_ng.found()}
2427 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2428 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2429 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2430 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2431 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2432 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2433 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2434 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2435 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2436 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2437 if config_host['TRACE_BACKENDS'].split().contains('simple')
2438 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2440 # TODO: add back protocol and server version
2441 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2442 summary_info += {'rbd support': rbd.found()}
2443 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2444 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2445 summary_info += {'U2F support': u2f.found()}
2446 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2447 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2448 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2449 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2450 summary_info += {'libiscsi support': libiscsi.found()}
2451 summary_info += {'libnfs support': libnfs.found()}
2452 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2453 if targetos == 'windows'
2454 if 'WIN_SDK' in config_host
2455 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2457 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2458 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2459 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2461 summary_info += {'seccomp support': seccomp.found()}
2462 summary_info += {'CFI support': get_option('cfi')}
2463 summary_info += {'CFI debug support': get_option('cfi_debug')}
2464 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2465 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2466 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2467 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2468 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2469 summary_info += {'GlusterFS support': glusterfs.found()}
2470 summary_info += {'gcov': get_option('b_coverage')}
2471 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2472 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2473 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2474 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2475 summary_info += {'lzo support': lzo.found()}
2476 summary_info += {'snappy support': snappy.found()}
2477 summary_info += {'bzip2 support': libbzip2.found()}
2478 summary_info += {'lzfse support': liblzfse.found()}
2479 summary_info += {'zstd support': zstd.found()}
2480 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2481 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2482 summary_info += {'memory allocator': get_option('malloc')}
2483 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2484 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2485 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2486 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2487 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2488 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2489 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2490 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2491 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2492 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2493 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2494 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2495 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2496 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2497 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2498 summary_info += {'libudev': libudev.found()}
2499 summary_info += {'default devices': get_option('default_devices')}
2500 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2501 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2502 if config_host.has_key('HAVE_GDB_BIN')
2503 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2505 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2506 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2507 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2508 summary_info += {'FUSE exports': fuse.found()}
2509 summary_info += {'FUSE lseek': fuse_lseek.found()}
2510 summary(summary_info, bool_yn: true)
2512 if not supported_cpus.contains(cpu)
2514 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2516 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2517 message('The QEMU project intends to remove support for this host CPU in')
2518 message('a future release if nobody volunteers to maintain it and to')
2519 message('provide a build host for our continuous integration setup.')
2520 message('configure has succeeded and you can continue to build, but')
2521 message('if you care about QEMU on this platform you should contact')
2525 if not supported_oses.contains(targetos)
2527 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2529 message('Host OS ' + targetos + 'support is not currently maintained.')
2530 message('The QEMU project intends to remove support for this host OS in')
2531 message('a future release if nobody volunteers to maintain it and to')
2532 message('provide a build host for our continuous integration setup.')
2533 message('configure has succeeded and you can continue to build, but')
2534 message('if you care about QEMU on this platform you should contact')