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)
332 if 'CONFIG_ATTR' in config_host
333 libattr = declare_dependency(link_args: config_host['LIBATTR_LIBS'].split())
336 if 'CONFIG_SECCOMP' in config_host
337 seccomp = declare_dependency(compile_args: config_host['SECCOMP_CFLAGS'].split(),
338 link_args: config_host['SECCOMP_LIBS'].split())
340 libcap_ng = not_found
341 if 'CONFIG_LIBCAP_NG' in config_host
342 libcap_ng = declare_dependency(link_args: config_host['LIBCAP_NG_LIBS'].split())
344 if get_option('xkbcommon').auto() and not have_system and not have_tools
345 xkbcommon = not_found
347 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
348 method: 'pkg-config', static: enable_static)
351 if config_host.has_key('CONFIG_VDE')
352 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
355 if 'CONFIG_LIBPULSE' in config_host
356 pulse = declare_dependency(compile_args: config_host['PULSE_CFLAGS'].split(),
357 link_args: config_host['PULSE_LIBS'].split())
360 if 'CONFIG_ALSA' in config_host
361 alsa = declare_dependency(compile_args: config_host['ALSA_CFLAGS'].split(),
362 link_args: config_host['ALSA_LIBS'].split())
365 if 'CONFIG_LIBJACK' in config_host
366 jack = declare_dependency(link_args: config_host['JACK_LIBS'].split())
369 spice_headers = not_found
370 if 'CONFIG_SPICE' in config_host
371 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
372 link_args: config_host['SPICE_LIBS'].split())
373 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
375 rt = cc.find_library('rt', required: false)
377 if 'CONFIG_PLUGIN' in config_host
378 libdl = cc.find_library('dl', required: true)
381 if not get_option('libiscsi').auto() or have_block
382 libiscsi = dependency('libiscsi', version: '>=1.9.0',
383 required: get_option('libiscsi'),
384 method: 'pkg-config', static: enable_static)
387 if 'CONFIG_ZSTD' in config_host
388 zstd = declare_dependency(compile_args: config_host['ZSTD_CFLAGS'].split(),
389 link_args: config_host['ZSTD_LIBS'].split())
392 if 'CONFIG_GBM' in config_host
393 gbm = declare_dependency(compile_args: config_host['GBM_CFLAGS'].split(),
394 link_args: config_host['GBM_LIBS'].split())
397 if 'CONFIG_VIRGL' in config_host
398 virgl = declare_dependency(compile_args: config_host['VIRGL_CFLAGS'].split(),
399 link_args: config_host['VIRGL_LIBS'].split())
402 if not get_option('curl').auto() or have_block
403 curl = dependency('libcurl', version: '>=7.29.0',
404 method: 'pkg-config',
405 required: get_option('curl'),
406 static: enable_static)
409 if targetos == 'linux' and (have_system or have_tools)
410 libudev = dependency('libudev',
411 method: 'pkg-config',
412 required: get_option('libudev'),
413 static: enable_static)
416 mpathlibs = [libudev]
417 mpathpersist = not_found
418 mpathpersist_new_api = false
419 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
420 mpath_test_source_new = '''
422 #include <mpath_persist.h>
423 unsigned mpath_mx_alloc_len = 1024;
425 static struct config *multipath_conf;
426 extern struct udev *udev;
427 extern struct config *get_multipath_config(void);
428 extern void put_multipath_config(struct config *conf);
430 struct config *get_multipath_config(void) { return multipath_conf; }
431 void put_multipath_config(struct config *conf) { }
434 multipath_conf = mpath_lib_init();
437 mpath_test_source_old = '''
439 #include <mpath_persist.h>
440 unsigned mpath_mx_alloc_len = 1024;
443 struct udev *udev = udev_new();
444 mpath_lib_init(udev);
447 libmpathpersist = cc.find_library('mpathpersist',
448 required: get_option('mpath'),
449 static: enable_static)
450 if libmpathpersist.found()
451 mpathlibs += libmpathpersist
453 mpathlibs += cc.find_library('devmapper',
454 required: get_option('mpath'),
455 static: enable_static)
457 mpathlibs += cc.find_library('multipath',
458 required: get_option('mpath'),
459 static: enable_static)
460 foreach lib: mpathlibs
466 if mpathlibs.length() == 0
467 msg = 'Dependencies missing for libmpathpersist'
468 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
469 mpathpersist = declare_dependency(dependencies: mpathlibs)
470 mpathpersist_new_api = true
471 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
472 mpathpersist = declare_dependency(dependencies: mpathlibs)
474 msg = 'Cannot detect libmpathpersist API'
476 if not mpathpersist.found()
477 if get_option('mpath').enabled()
480 warning(msg + ', disabling')
488 if have_system and not get_option('curses').disabled()
495 setlocale(LC_ALL, "");
497 addwstr(L"wide chars\n");
499 add_wch(WACS_DEGREE);
503 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
504 foreach curses_dep : curses_dep_list
505 if not curses.found()
506 curses = dependency(curses_dep,
508 method: 'pkg-config',
509 static: enable_static)
512 msg = get_option('curses').enabled() ? 'curses library not found' : ''
513 curses_compile_args = ['-DNCURSES_WIDECHAR']
515 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
516 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
518 msg = 'curses package not usable'
522 if not curses.found()
523 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
524 if targetos != 'windows' and not has_curses_h
525 message('Trying with /usr/include/ncursesw')
526 curses_compile_args += ['-I/usr/include/ncursesw']
527 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
530 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
531 foreach curses_libname : curses_libname_list
532 libcurses = cc.find_library(curses_libname,
534 static: enable_static)
536 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
537 curses = declare_dependency(compile_args: curses_compile_args,
538 dependencies: [libcurses])
541 msg = 'curses library not usable'
547 if not get_option('iconv').disabled()
548 foreach link_args : [ ['-liconv'], [] ]
549 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
550 # We need to use libiconv if available because mixing libiconv's headers with
551 # the system libc does not work.
552 # However, without adding glib to the dependencies -L/usr/local/lib will not be
553 # included in the command line and libiconv will not be found.
557 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
558 return conv != (iconv_t) -1;
559 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
560 iconv = declare_dependency(link_args: link_args, dependencies: glib)
565 if curses.found() and not iconv.found()
566 if get_option('iconv').enabled()
567 error('iconv not available')
569 msg = 'iconv required for curses UI but not available'
572 if not curses.found() and msg != ''
573 if get_option('curses').enabled()
576 warning(msg + ', disabling')
582 if not get_option('brlapi').auto() or have_system
583 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
584 required: get_option('brlapi'),
585 static: enable_static)
586 if brlapi.found() and not cc.links('''
589 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
591 if get_option('brlapi').enabled()
592 error('could not link brlapi')
594 warning('could not link brlapi, disabling')
601 sdl = dependency('sdl2', required: get_option('sdl'), static: enable_static)
602 sdl_image = not_found
605 # work around 2.0.8 bug
606 sdl = declare_dependency(compile_args: '-Wno-undef',
608 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
609 method: 'pkg-config', static: enable_static)
611 if get_option('sdl_image').enabled()
612 error('sdl-image required, but SDL was @0@'.format(
613 get_option('sdl').disabled() ? 'disabled' : 'not found'))
615 sdl_image = not_found
619 if not get_option('rbd').auto() or have_block
620 librados = cc.find_library('rados', required: get_option('rbd'),
621 static: enable_static)
622 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
623 required: get_option('rbd'),
624 static: enable_static)
625 if librados.found() and librbd.found() and cc.links('''
627 #include <rbd/librbd.h>
630 rados_create(&cluster, NULL);
632 }''', dependencies: [librbd, librados])
633 rbd = declare_dependency(dependencies: [librbd, librados])
637 glusterfs = not_found
638 glusterfs_ftruncate_has_stat = false
639 glusterfs_iocb_has_stat = false
640 if not get_option('glusterfs').auto() or have_block
641 glusterfs = dependency('glusterfs-api', version: '>=3',
642 required: get_option('glusterfs'),
643 method: 'pkg-config', static: enable_static)
645 glusterfs_ftruncate_has_stat = cc.links('''
646 #include <glusterfs/api/glfs.h>
651 /* new glfs_ftruncate() passes two additional args */
652 return glfs_ftruncate(NULL, 0, NULL, NULL);
654 ''', dependencies: glusterfs)
655 glusterfs_iocb_has_stat = cc.links('''
656 #include <glusterfs/api/glfs.h>
658 /* new glfs_io_cbk() passes two additional glfs_stat structs */
660 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
666 glfs_io_cbk iocb = &glusterfs_iocb;
667 iocb(NULL, 0 , NULL, NULL, NULL);
670 ''', dependencies: glusterfs)
674 if 'CONFIG_LIBSSH' in config_host
675 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
676 link_args: config_host['LIBSSH_LIBS'].split())
679 if not get_option('bzip2').auto() or have_block
680 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
681 required: get_option('bzip2'),
682 static: enable_static)
683 if libbzip2.found() and not cc.links('''
685 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
687 if get_option('bzip2').enabled()
688 error('could not link libbzip2')
690 warning('could not link libbzip2, disabling')
695 if 'CONFIG_LZFSE' in config_host
696 liblzfse = declare_dependency(link_args: config_host['LZFSE_LIBS'].split())
699 if 'CONFIG_AUDIO_OSS' in config_host
700 oss = declare_dependency(link_args: config_host['OSS_LIBS'].split())
703 if 'CONFIG_AUDIO_DSOUND' in config_host
704 dsound = declare_dependency(link_args: config_host['DSOUND_LIBS'].split())
706 coreaudio = not_found
707 if 'CONFIG_AUDIO_COREAUDIO' in config_host
708 coreaudio = declare_dependency(link_args: config_host['COREAUDIO_LIBS'].split())
711 if 'CONFIG_OPENGL' in config_host
712 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
713 link_args: config_host['OPENGL_LIBS'].split())
716 if 'CONFIG_GTK' in config_host
717 gtk = declare_dependency(compile_args: config_host['GTK_CFLAGS'].split(),
718 link_args: config_host['GTK_LIBS'].split())
721 if 'CONFIG_VTE' in config_host
722 vte = declare_dependency(compile_args: config_host['VTE_CFLAGS'].split(),
723 link_args: config_host['VTE_LIBS'].split())
726 if 'CONFIG_X11' in config_host
727 x11 = declare_dependency(compile_args: config_host['X11_CFLAGS'].split(),
728 link_args: config_host['X11_LIBS'].split())
734 if get_option('vnc').enabled()
735 vnc = declare_dependency() # dummy dependency
736 png = dependency('libpng', required: get_option('vnc_png'),
737 method: 'pkg-config', static: enable_static)
738 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
739 method: 'pkg-config', static: enable_static)
740 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
741 required: get_option('vnc_sasl'),
742 static: enable_static)
744 sasl = declare_dependency(dependencies: sasl,
745 compile_args: '-DSTRUCT_IOVEC_DEFINED')
750 if not get_option('snappy').auto() or have_system
751 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
752 required: get_option('snappy'),
753 static: enable_static)
755 if snappy.found() and not cc.links('''
756 #include <snappy-c.h>
757 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
759 if get_option('snappy').enabled()
760 error('could not link libsnappy')
762 warning('could not link libsnappy, disabling')
767 if not get_option('lzo').auto() or have_system
768 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
769 required: get_option('lzo'),
770 static: enable_static)
772 if lzo.found() and not cc.links('''
773 #include <lzo/lzo1x.h>
774 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
776 if get_option('lzo').enabled()
777 error('could not link liblzo2')
779 warning('could not link liblzo2, disabling')
784 if 'CONFIG_RDMA' in config_host
785 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
788 if 'CONFIG_NUMA' in config_host
789 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
792 if 'CONFIG_XEN_BACKEND' in config_host
793 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
794 link_args: config_host['XEN_LIBS'].split())
797 if 'CONFIG_SMARTCARD' in config_host
798 cacard = declare_dependency(compile_args: config_host['SMARTCARD_CFLAGS'].split(),
799 link_args: config_host['SMARTCARD_LIBS'].split())
803 u2f = dependency('u2f-emu', required: get_option('u2f'),
804 method: 'pkg-config',
805 static: enable_static)
808 if 'CONFIG_USB_REDIR' in config_host
809 usbredir = declare_dependency(compile_args: config_host['USB_REDIR_CFLAGS'].split(),
810 link_args: config_host['USB_REDIR_LIBS'].split())
813 if 'CONFIG_USB_LIBUSB' in config_host
814 libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
815 link_args: config_host['LIBUSB_LIBS'].split())
818 if 'CONFIG_LIBPMEM' in config_host
819 libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
820 link_args: config_host['LIBPMEM_LIBS'].split())
822 libdaxctl = not_found
823 if 'CONFIG_LIBDAXCTL' in config_host
824 libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
827 if 'CONFIG_TASN1' in config_host
828 tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
829 link_args: config_host['TASN1_LIBS'].split())
831 keyutils = dependency('libkeyutils', required: false,
832 method: 'pkg-config', static: enable_static)
834 has_gettid = cc.has_function('gettid')
839 if get_option('malloc') == 'system'
841 not get_option('malloc_trim').disabled() and \
842 cc.links('''#include <malloc.h>
843 int main(void) { malloc_trim(0); return 0; }''')
845 has_malloc_trim = false
846 malloc = cc.find_library(get_option('malloc'), required: true)
848 if not has_malloc_trim and get_option('malloc_trim').enabled()
849 if get_option('malloc') == 'system'
850 error('malloc_trim not available on this platform.')
852 error('malloc_trim not available with non-libc memory allocator')
856 # Check whether the glibc provides statx()
862 #include <sys/stat.h>
864 struct statx statxbuf;
865 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
869 has_statx = cc.links(statx_test)
871 have_vhost_user_blk_server = (targetos == 'linux' and
872 'CONFIG_VHOST_USER' in config_host)
874 if get_option('vhost_user_blk_server').enabled()
875 if targetos != 'linux'
876 error('vhost_user_blk_server requires linux')
877 elif 'CONFIG_VHOST_USER' not in config_host
878 error('vhost_user_blk_server requires vhost-user support')
880 elif get_option('vhost_user_blk_server').disabled() or not have_system
881 have_vhost_user_blk_server = false
885 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
886 error('Cannot enable fuse-lseek while fuse is disabled')
889 fuse = dependency('fuse3', required: get_option('fuse'),
890 version: '>=3.1', method: 'pkg-config',
891 static: enable_static)
893 fuse_lseek = not_found
894 if not get_option('fuse_lseek').disabled()
895 if fuse.version().version_compare('>=3.8')
897 fuse_lseek = declare_dependency()
898 elif get_option('fuse_lseek').enabled()
900 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
902 error('fuse-lseek requires libfuse, which was not found')
909 # Check for dependency on LTO
910 if not get_option('b_lto')
911 error('Selected Control-Flow Integrity but LTO is disabled')
913 if config_host.has_key('CONFIG_MODULES')
914 error('Selected Control-Flow Integrity is not compatible with modules')
916 # Check for cfi flags. CFI requires LTO so we can't use
917 # get_supported_arguments, but need a more complex "compiles" which allows
919 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
920 args: ['-flto', '-fsanitize=cfi-icall'] )
921 cfi_flags += '-fsanitize=cfi-icall'
923 error('-fsanitize=cfi-icall is not supported by the compiler')
925 if cc.compiles('int main () { return 0; }',
926 name: '-fsanitize-cfi-icall-generalize-pointers',
927 args: ['-flto', '-fsanitize=cfi-icall',
928 '-fsanitize-cfi-icall-generalize-pointers'] )
929 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
931 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
933 if get_option('cfi_debug')
934 if cc.compiles('int main () { return 0; }',
935 name: '-fno-sanitize-trap=cfi-icall',
936 args: ['-flto', '-fsanitize=cfi-icall',
937 '-fno-sanitize-trap=cfi-icall'] )
938 cfi_flags += '-fno-sanitize-trap=cfi-icall'
940 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
943 add_project_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
944 add_project_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
951 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
952 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
953 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
954 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
955 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
956 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
957 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
958 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
959 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
960 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
961 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
962 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
964 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
965 config_host_data.set('CONFIG_COCOA', cocoa.found())
966 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
967 config_host_data.set('CONFIG_LZO', lzo.found())
968 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
969 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
970 config_host_data.set('CONFIG_CURL', curl.found())
971 config_host_data.set('CONFIG_CURSES', curses.found())
972 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
974 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
975 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
976 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
977 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
978 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
979 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
981 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
982 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
983 config_host_data.set('CONFIG_RBD', rbd.found())
984 config_host_data.set('CONFIG_SDL', sdl.found())
985 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
986 config_host_data.set('CONFIG_SNAPPY', snappy.found())
987 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
988 config_host_data.set('CONFIG_VNC', vnc.found())
989 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
990 config_host_data.set('CONFIG_VNC_PNG', png.found())
991 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
992 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
993 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
994 config_host_data.set('CONFIG_GETTID', has_gettid)
995 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
996 config_host_data.set('CONFIG_STATX', has_statx)
997 config_host_data.set('CONFIG_FUSE', fuse.found())
998 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
999 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1000 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1001 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1002 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1003 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1005 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1006 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1007 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1008 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1009 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1010 config_host_data.set('HAVE_SYS_SIGNAL_H', cc.has_header('sys/signal.h'))
1012 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1013 arrays = ['CONFIG_AUDIO_DRIVERS', 'CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1014 strings = ['HOST_DSOSUF', 'CONFIG_IASL']
1015 foreach k, v: config_host
1016 if ignored.contains(k)
1018 elif arrays.contains(k)
1020 v = '"' + '", "'.join(v.split()) + '", '
1022 config_host_data.set(k, v)
1024 config_host_data.set('HOST_' + v.to_upper(), 1)
1025 elif strings.contains(k)
1026 if not k.startswith('CONFIG_')
1027 k = 'CONFIG_' + k.to_upper()
1029 config_host_data.set_quoted(k, v)
1030 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1031 config_host_data.set(k, v == 'y' ? 1 : v)
1035 ########################
1036 # Target configuration #
1037 ########################
1039 minikconf = find_program('scripts/minikconf.py')
1041 config_all_devices = {}
1042 config_all_disas = {}
1043 config_devices_mak_list = []
1044 config_devices_h = {}
1045 config_target_h = {}
1046 config_target_mak = {}
1049 'alpha' : ['CONFIG_ALPHA_DIS'],
1050 'arm' : ['CONFIG_ARM_DIS'],
1051 'avr' : ['CONFIG_AVR_DIS'],
1052 'cris' : ['CONFIG_CRIS_DIS'],
1053 'hppa' : ['CONFIG_HPPA_DIS'],
1054 'i386' : ['CONFIG_I386_DIS'],
1055 'x86_64' : ['CONFIG_I386_DIS'],
1056 'x32' : ['CONFIG_I386_DIS'],
1057 'lm32' : ['CONFIG_LM32_DIS'],
1058 'm68k' : ['CONFIG_M68K_DIS'],
1059 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1060 'mips' : ['CONFIG_MIPS_DIS'],
1061 'moxie' : ['CONFIG_MOXIE_DIS'],
1062 'nios2' : ['CONFIG_NIOS2_DIS'],
1063 'or1k' : ['CONFIG_OPENRISC_DIS'],
1064 'ppc' : ['CONFIG_PPC_DIS'],
1065 'riscv' : ['CONFIG_RISCV_DIS'],
1066 'rx' : ['CONFIG_RX_DIS'],
1067 's390' : ['CONFIG_S390_DIS'],
1068 'sh4' : ['CONFIG_SH4_DIS'],
1069 'sparc' : ['CONFIG_SPARC_DIS'],
1070 'xtensa' : ['CONFIG_XTENSA_DIS'],
1072 if link_language == 'cpp'
1074 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1075 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1076 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1081 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1082 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1083 ('CONFIG_IVSHMEM' in config_host ? ['CONFIG_IVSHMEM=y'] : []) + \
1084 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1085 ('CONFIG_X11' in config_host ? ['CONFIG_X11=y'] : []) + \
1086 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1087 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1088 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1089 ('CONFIG_VIRTFS' in config_host ? ['CONFIG_VIRTFS=y'] : []) + \
1090 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1091 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : [])
1093 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1095 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1096 actual_target_dirs = []
1098 foreach target : target_dirs
1099 config_target = { 'TARGET_NAME': target.split('-')[0] }
1100 if target.endswith('linux-user')
1101 if targetos != 'linux'
1105 error('Target @0@ is only available on a Linux host'.format(target))
1107 config_target += { 'CONFIG_LINUX_USER': 'y' }
1108 elif target.endswith('bsd-user')
1109 if 'CONFIG_BSD' not in config_host
1113 error('Target @0@ is only available on a BSD host'.format(target))
1115 config_target += { 'CONFIG_BSD_USER': 'y' }
1116 elif target.endswith('softmmu')
1117 config_target += { 'CONFIG_SOFTMMU': 'y' }
1119 if target.endswith('-user')
1121 'CONFIG_USER_ONLY': 'y',
1122 'CONFIG_QEMU_INTERP_PREFIX':
1123 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1128 foreach sym: accelerators
1129 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1130 config_target += { sym: 'y' }
1131 config_all += { sym: 'y' }
1132 if sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1133 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1135 accel_kconfig += [ sym + '=y' ]
1138 if accel_kconfig.length() == 0
1142 error('No accelerator available for target @0@'.format(target))
1145 actual_target_dirs += target
1146 config_target += keyval.load('default-configs/targets' / target + '.mak')
1147 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1149 if 'TARGET_NEED_FDT' in config_target
1150 fdt_required += target
1154 if 'TARGET_BASE_ARCH' not in config_target
1155 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1157 if 'TARGET_ABI_DIR' not in config_target
1158 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1161 foreach k, v: disassemblers
1162 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1164 config_target += { sym: 'y' }
1165 config_all_disas += { sym: 'y' }
1170 config_target_data = configuration_data()
1171 foreach k, v: config_target
1172 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1174 elif ignored.contains(k)
1176 elif k == 'TARGET_BASE_ARCH'
1177 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1178 # not used to select files from sourcesets.
1179 config_target_data.set('TARGET_' + v.to_upper(), 1)
1180 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1181 config_target_data.set_quoted(k, v)
1183 config_target_data.set(k, 1)
1185 config_target_data.set(k, v)
1188 config_target_h += {target: configure_file(output: target + '-config-target.h',
1189 configuration: config_target_data)}
1191 if target.endswith('-softmmu')
1192 config_devices_mak = target + '-config-devices.mak'
1193 config_devices_mak = configure_file(
1194 input: ['default-configs/devices' / target + '.mak', 'Kconfig'],
1195 output: config_devices_mak,
1196 depfile: config_devices_mak + '.d',
1198 command: [minikconf, config_host['CONFIG_MINIKCONF_MODE'],
1199 config_devices_mak, '@DEPFILE@', '@INPUT@',
1200 host_kconfig, accel_kconfig])
1202 config_devices_data = configuration_data()
1203 config_devices = keyval.load(config_devices_mak)
1204 foreach k, v: config_devices
1205 config_devices_data.set(k, 1)
1207 config_devices_mak_list += config_devices_mak
1208 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1209 configuration: config_devices_data)}
1210 config_target += config_devices
1211 config_all_devices += config_devices
1213 config_target_mak += {target: config_target}
1215 target_dirs = actual_target_dirs
1217 # This configuration is used to build files that are shared by
1218 # multiple binaries, and then extracted out of the "common"
1219 # static_library target.
1221 # We do not use all_sources()/all_dependencies(), because it would
1222 # build literally all source files, including devices only used by
1223 # targets that are not built for this compilation. The CONFIG_ALL
1224 # pseudo symbol replaces it.
1226 config_all += config_all_devices
1227 config_all += config_host
1228 config_all += config_all_disas
1230 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1231 'CONFIG_SOFTMMU': have_system,
1232 'CONFIG_USER_ONLY': have_user,
1240 capstone = not_found
1241 capstone_opt = get_option('capstone')
1242 if capstone_opt in ['enabled', 'auto', 'system']
1243 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1244 capstone = dependency('capstone', version: '>=4.0',
1245 static: enable_static, method: 'pkg-config',
1246 required: capstone_opt == 'system' or
1247 capstone_opt == 'enabled' and not have_internal)
1249 capstone_opt = 'system'
1251 capstone_opt = 'internal'
1253 capstone_opt = 'disabled'
1256 if capstone_opt == 'internal'
1257 capstone_data = configuration_data()
1258 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1260 capstone_files = files(
1262 'capstone/MCInst.c',
1263 'capstone/MCInstrDesc.c',
1264 'capstone/MCRegisterInfo.c',
1265 'capstone/SStream.c',
1269 if 'CONFIG_ARM_DIS' in config_all_disas
1270 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1271 capstone_files += files(
1272 'capstone/arch/ARM/ARMDisassembler.c',
1273 'capstone/arch/ARM/ARMInstPrinter.c',
1274 'capstone/arch/ARM/ARMMapping.c',
1275 'capstone/arch/ARM/ARMModule.c'
1279 # FIXME: This config entry currently depends on a c++ compiler.
1280 # Which is needed for building libvixl, but not for capstone.
1281 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1282 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1283 capstone_files += files(
1284 'capstone/arch/AArch64/AArch64BaseInfo.c',
1285 'capstone/arch/AArch64/AArch64Disassembler.c',
1286 'capstone/arch/AArch64/AArch64InstPrinter.c',
1287 'capstone/arch/AArch64/AArch64Mapping.c',
1288 'capstone/arch/AArch64/AArch64Module.c'
1292 if 'CONFIG_PPC_DIS' in config_all_disas
1293 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1294 capstone_files += files(
1295 'capstone/arch/PowerPC/PPCDisassembler.c',
1296 'capstone/arch/PowerPC/PPCInstPrinter.c',
1297 'capstone/arch/PowerPC/PPCMapping.c',
1298 'capstone/arch/PowerPC/PPCModule.c'
1302 if 'CONFIG_S390_DIS' in config_all_disas
1303 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1304 capstone_files += files(
1305 'capstone/arch/SystemZ/SystemZDisassembler.c',
1306 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1307 'capstone/arch/SystemZ/SystemZMapping.c',
1308 'capstone/arch/SystemZ/SystemZModule.c',
1309 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1313 if 'CONFIG_I386_DIS' in config_all_disas
1314 capstone_data.set('CAPSTONE_HAS_X86', 1)
1315 capstone_files += files(
1316 'capstone/arch/X86/X86Disassembler.c',
1317 'capstone/arch/X86/X86DisassemblerDecoder.c',
1318 'capstone/arch/X86/X86ATTInstPrinter.c',
1319 'capstone/arch/X86/X86IntelInstPrinter.c',
1320 'capstone/arch/X86/X86InstPrinterCommon.c',
1321 'capstone/arch/X86/X86Mapping.c',
1322 'capstone/arch/X86/X86Module.c'
1326 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1329 # FIXME: There does not seem to be a way to completely replace the c_args
1330 # that come from add_project_arguments() -- we can only add to them.
1331 # So: disable all warnings with a big hammer.
1334 # Include all configuration defines via a header file, which will wind up
1335 # as a dependency on the object file, and thus changes here will result
1337 '-include', 'capstone-defs.h'
1340 libcapstone = static_library('capstone',
1341 sources: capstone_files,
1342 c_args: capstone_cargs,
1343 include_directories: 'capstone/include')
1344 capstone = declare_dependency(link_with: libcapstone,
1345 include_directories: 'capstone/include/capstone')
1349 slirp_opt = 'disabled'
1351 slirp_opt = get_option('slirp')
1352 if slirp_opt in ['enabled', 'auto', 'system']
1353 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1354 slirp = dependency('slirp', static: enable_static,
1355 method: 'pkg-config',
1356 required: slirp_opt == 'system' or
1357 slirp_opt == 'enabled' and not have_internal)
1359 slirp_opt = 'system'
1361 slirp_opt = 'internal'
1363 slirp_opt = 'disabled'
1366 if slirp_opt == 'internal'
1368 if targetos == 'windows'
1369 slirp_deps = cc.find_library('iphlpapi')
1371 slirp_conf = configuration_data()
1372 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1373 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1374 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1375 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1376 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1378 'slirp/src/arp_table.c',
1379 'slirp/src/bootp.c',
1380 'slirp/src/cksum.c',
1381 'slirp/src/dhcpv6.c',
1382 'slirp/src/dnssearch.c',
1384 'slirp/src/ip6_icmp.c',
1385 'slirp/src/ip6_input.c',
1386 'slirp/src/ip6_output.c',
1387 'slirp/src/ip_icmp.c',
1388 'slirp/src/ip_input.c',
1389 'slirp/src/ip_output.c',
1393 'slirp/src/ndp_table.c',
1395 'slirp/src/slirp.c',
1396 'slirp/src/socket.c',
1397 'slirp/src/state.c',
1398 'slirp/src/stream.c',
1399 'slirp/src/tcp_input.c',
1400 'slirp/src/tcp_output.c',
1401 'slirp/src/tcp_subr.c',
1402 'slirp/src/tcp_timer.c',
1407 'slirp/src/version.c',
1408 'slirp/src/vmstate.c',
1412 input : 'slirp/src/libslirp-version.h.in',
1413 output : 'libslirp-version.h',
1414 configuration: slirp_conf)
1416 slirp_inc = include_directories('slirp', 'slirp/src')
1417 libslirp = static_library('slirp',
1418 sources: slirp_files,
1419 c_args: slirp_cargs,
1420 include_directories: slirp_inc)
1421 slirp = declare_dependency(link_with: libslirp,
1422 dependencies: slirp_deps,
1423 include_directories: slirp_inc)
1428 fdt_opt = get_option('fdt')
1430 if fdt_opt in ['enabled', 'auto', 'system']
1431 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
1432 fdt = cc.find_library('fdt', static: enable_static,
1433 required: fdt_opt == 'system' or
1434 fdt_opt == 'enabled' and not have_internal)
1435 if fdt.found() and cc.links('''
1437 #include <libfdt_env.h>
1438 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
1442 fdt_opt = 'internal'
1444 fdt_opt = 'disabled'
1447 if fdt_opt == 'internal'
1450 'dtc/libfdt/fdt_ro.c',
1451 'dtc/libfdt/fdt_wip.c',
1452 'dtc/libfdt/fdt_sw.c',
1453 'dtc/libfdt/fdt_rw.c',
1454 'dtc/libfdt/fdt_strerror.c',
1455 'dtc/libfdt/fdt_empty_tree.c',
1456 'dtc/libfdt/fdt_addresses.c',
1457 'dtc/libfdt/fdt_overlay.c',
1458 'dtc/libfdt/fdt_check.c',
1461 fdt_inc = include_directories('dtc/libfdt')
1462 libfdt = static_library('fdt',
1464 include_directories: fdt_inc)
1465 fdt = declare_dependency(link_with: libfdt,
1466 include_directories: fdt_inc)
1469 if not fdt.found() and fdt_required.length() > 0
1470 error('fdt not available but required by targets ' + ', '.join(fdt_required))
1473 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
1474 config_host_data.set('CONFIG_FDT', fdt.found())
1475 config_host_data.set('CONFIG_SLIRP', slirp.found())
1477 #####################
1478 # Generated sources #
1479 #####################
1481 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
1483 hxtool = find_program('scripts/hxtool')
1484 shaderinclude = find_program('scripts/shaderinclude.pl')
1485 qapi_gen = find_program('scripts/qapi-gen.py')
1486 qapi_gen_depends = [ meson.source_root() / 'scripts/qapi/__init__.py',
1487 meson.source_root() / 'scripts/qapi/commands.py',
1488 meson.source_root() / 'scripts/qapi/common.py',
1489 meson.source_root() / 'scripts/qapi/error.py',
1490 meson.source_root() / 'scripts/qapi/events.py',
1491 meson.source_root() / 'scripts/qapi/expr.py',
1492 meson.source_root() / 'scripts/qapi/gen.py',
1493 meson.source_root() / 'scripts/qapi/introspect.py',
1494 meson.source_root() / 'scripts/qapi/parser.py',
1495 meson.source_root() / 'scripts/qapi/schema.py',
1496 meson.source_root() / 'scripts/qapi/source.py',
1497 meson.source_root() / 'scripts/qapi/types.py',
1498 meson.source_root() / 'scripts/qapi/visit.py',
1499 meson.source_root() / 'scripts/qapi/common.py',
1500 meson.source_root() / 'scripts/qapi-gen.py'
1504 python, files('scripts/tracetool.py'),
1505 '--backend=' + config_host['TRACE_BACKENDS']
1508 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
1509 meson.current_source_dir(),
1510 config_host['PKGVERSION'], meson.project_version()]
1511 qemu_version = custom_target('qemu-version.h',
1512 output: 'qemu-version.h',
1513 command: qemu_version_cmd,
1515 build_by_default: true,
1516 build_always_stale: true)
1517 genh += qemu_version
1521 ['qemu-options.hx', 'qemu-options.def'],
1522 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
1526 ['hmp-commands.hx', 'hmp-commands.h'],
1527 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
1530 foreach d : hx_headers
1531 hxdep += custom_target(d[1],
1535 build_by_default: true, # to be removed when added to a target
1536 command: [hxtool, '-h', '@INPUT0@'])
1544 authz_ss = ss.source_set()
1545 blockdev_ss = ss.source_set()
1546 block_ss = ss.source_set()
1547 bsd_user_ss = ss.source_set()
1548 chardev_ss = ss.source_set()
1549 common_ss = ss.source_set()
1550 crypto_ss = ss.source_set()
1551 io_ss = ss.source_set()
1552 linux_user_ss = ss.source_set()
1553 qmp_ss = ss.source_set()
1554 qom_ss = ss.source_set()
1555 softmmu_ss = ss.source_set()
1556 specific_fuzz_ss = ss.source_set()
1557 specific_ss = ss.source_set()
1558 stub_ss = ss.source_set()
1559 trace_ss = ss.source_set()
1560 user_ss = ss.source_set()
1561 util_ss = ss.source_set()
1566 target_softmmu_arch = {}
1572 # TODO: add each directory to the subdirs from its own meson.build, once
1574 trace_events_subdirs = [
1581 trace_events_subdirs += [ 'linux-user' ]
1584 trace_events_subdirs += [
1593 trace_events_subdirs += [
1604 'hw/block/dataplane',
1650 trace_events_subdirs += [
1666 vhost_user = not_found
1667 if 'CONFIG_VHOST_USER' in config_host
1668 libvhost_user = subproject('libvhost-user')
1669 vhost_user = libvhost_user.get_variable('vhost_user_dep')
1684 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
1685 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
1688 stub_ss = stub_ss.apply(config_all, strict: false)
1690 util_ss.add_all(trace_ss)
1691 util_ss = util_ss.apply(config_all, strict: false)
1692 libqemuutil = static_library('qemuutil',
1693 sources: util_ss.sources() + stub_ss.sources() + genh,
1694 dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
1695 qemuutil = declare_dependency(link_with: libqemuutil,
1696 sources: genh + version_res)
1698 decodetree = generator(find_program('scripts/decodetree.py'),
1699 output: 'decode-@BASENAME@.c.inc',
1700 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
1706 subdir('libdecnumber')
1716 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
1722 blockdev_ss.add(files(
1729 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
1730 # os-win32.c does not
1731 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
1732 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
1734 common_ss.add(files('cpus-common.c'))
1738 common_ss.add(capstone)
1739 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
1740 specific_ss.add(files('exec-vary.c'))
1741 specific_ss.add(when: 'CONFIG_TCG', if_true: files(
1745 'tcg/tcg-op-gvec.c',
1750 specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('disas/tci.c', 'tcg/tci.c'))
1762 subdir('linux-user')
1764 bsd_user_ss.add(files('gdbstub.c'))
1765 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
1767 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
1768 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
1770 # needed for fuzzing binaries
1771 subdir('tests/qtest/libqos')
1772 subdir('tests/qtest/fuzz')
1774 ########################
1775 # Library dependencies #
1776 ########################
1780 foreach d, list : modules
1781 foreach m, module_ss : list
1782 if enable_modules and targetos != 'windows'
1783 module_ss = module_ss.apply(config_all, strict: false)
1784 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
1785 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
1793 block_ss.add_all(module_ss)
1795 softmmu_ss.add_all(module_ss)
1801 nm = find_program('nm')
1802 undefsym = find_program('scripts/undefsym.py')
1803 block_syms = custom_target('block.syms', output: 'block.syms',
1804 input: [libqemuutil, block_mods],
1806 command: [undefsym, nm, '@INPUT@'])
1807 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
1808 input: [libqemuutil, softmmu_mods],
1810 command: [undefsym, nm, '@INPUT@'])
1812 qom_ss = qom_ss.apply(config_host, strict: false)
1813 libqom = static_library('qom', qom_ss.sources() + genh,
1814 dependencies: [qom_ss.dependencies()],
1817 qom = declare_dependency(link_whole: libqom)
1819 authz_ss = authz_ss.apply(config_host, strict: false)
1820 libauthz = static_library('authz', authz_ss.sources() + genh,
1821 dependencies: [authz_ss.dependencies()],
1823 build_by_default: false)
1825 authz = declare_dependency(link_whole: libauthz,
1828 crypto_ss = crypto_ss.apply(config_host, strict: false)
1829 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
1830 dependencies: [crypto_ss.dependencies()],
1832 build_by_default: false)
1834 crypto = declare_dependency(link_whole: libcrypto,
1835 dependencies: [authz, qom])
1837 io_ss = io_ss.apply(config_host, strict: false)
1838 libio = static_library('io', io_ss.sources() + genh,
1839 dependencies: [io_ss.dependencies()],
1840 link_with: libqemuutil,
1842 build_by_default: false)
1844 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
1846 libmigration = static_library('migration', sources: migration_files + genh,
1848 build_by_default: false)
1849 migration = declare_dependency(link_with: libmigration,
1850 dependencies: [zlib, qom, io])
1851 softmmu_ss.add(migration)
1853 block_ss = block_ss.apply(config_host, strict: false)
1854 libblock = static_library('block', block_ss.sources() + genh,
1855 dependencies: block_ss.dependencies(),
1856 link_depends: block_syms,
1858 build_by_default: false)
1860 block = declare_dependency(link_whole: [libblock],
1861 link_args: '@block.syms',
1862 dependencies: [crypto, io])
1864 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
1865 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
1866 dependencies: blockdev_ss.dependencies(),
1868 build_by_default: false)
1870 blockdev = declare_dependency(link_whole: [libblockdev],
1871 dependencies: [block])
1873 qmp_ss = qmp_ss.apply(config_host, strict: false)
1874 libqmp = static_library('qmp', qmp_ss.sources() + genh,
1875 dependencies: qmp_ss.dependencies(),
1877 build_by_default: false)
1879 qmp = declare_dependency(link_whole: [libqmp])
1881 libchardev = static_library('chardev', chardev_ss.sources() + genh,
1883 build_by_default: false)
1885 chardev = declare_dependency(link_whole: libchardev)
1887 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
1889 build_by_default: false)
1890 hwcore = declare_dependency(link_whole: libhwcore)
1891 common_ss.add(hwcore)
1897 foreach m : block_mods + softmmu_mods
1898 shared_module(m.name(),
1902 install_dir: qemu_moddir)
1905 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
1906 common_ss.add(qom, qemuutil)
1908 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
1909 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
1911 common_all = common_ss.apply(config_all, strict: false)
1912 common_all = static_library('common',
1913 build_by_default: false,
1914 sources: common_all.sources() + genh,
1915 dependencies: common_all.dependencies(),
1918 feature_to_c = find_program('scripts/feature_to_c.sh')
1921 foreach target : target_dirs
1922 config_target = config_target_mak[target]
1923 target_name = config_target['TARGET_NAME']
1924 arch = config_target['TARGET_BASE_ARCH']
1925 arch_srcs = [config_target_h[target]]
1927 c_args = ['-DNEED_CPU_H',
1928 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
1929 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
1930 link_args = emulator_link_args
1932 config_target += config_host
1933 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
1934 if targetos == 'linux'
1935 target_inc += include_directories('linux-headers', is_system: true)
1937 if target.endswith('-softmmu')
1938 qemu_target_name = 'qemu-system-' + target_name
1939 target_type='system'
1940 t = target_softmmu_arch[arch].apply(config_target, strict: false)
1941 arch_srcs += t.sources()
1942 arch_deps += t.dependencies()
1944 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
1945 hw = hw_arch[hw_dir].apply(config_target, strict: false)
1946 arch_srcs += hw.sources()
1947 arch_deps += hw.dependencies()
1949 arch_srcs += config_devices_h[target]
1950 link_args += ['@block.syms', '@qemu.syms']
1952 abi = config_target['TARGET_ABI_DIR']
1954 qemu_target_name = 'qemu-' + target_name
1955 if 'CONFIG_LINUX_USER' in config_target
1956 base_dir = 'linux-user'
1957 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
1959 base_dir = 'bsd-user'
1961 target_inc += include_directories(
1965 if 'CONFIG_LINUX_USER' in config_target
1966 dir = base_dir / abi
1967 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
1968 if config_target.has_key('TARGET_SYSTBL_ABI')
1970 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
1971 extra_args : config_target['TARGET_SYSTBL_ABI'])
1976 if 'TARGET_XML_FILES' in config_target
1977 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
1978 output: target + '-gdbstub-xml.c',
1979 input: files(config_target['TARGET_XML_FILES'].split()),
1980 command: [feature_to_c, '@INPUT@'],
1982 arch_srcs += gdbstub_xml
1985 t = target_arch[arch].apply(config_target, strict: false)
1986 arch_srcs += t.sources()
1987 arch_deps += t.dependencies()
1989 target_common = common_ss.apply(config_target, strict: false)
1990 objects = common_all.extract_objects(target_common.sources())
1991 deps = target_common.dependencies()
1993 target_specific = specific_ss.apply(config_target, strict: false)
1994 arch_srcs += target_specific.sources()
1995 arch_deps += target_specific.dependencies()
1997 lib = static_library('qemu-' + target,
1998 sources: arch_srcs + genh,
1999 dependencies: arch_deps,
2001 include_directories: target_inc,
2003 build_by_default: false,
2006 if target.endswith('-softmmu')
2008 'name': 'qemu-system-' + target_name,
2010 'sources': files('softmmu/main.c'),
2013 if targetos == 'windows' and (sdl.found() or gtk.found())
2015 'name': 'qemu-system-' + target_name + 'w',
2017 'sources': files('softmmu/main.c'),
2021 if config_host.has_key('CONFIG_FUZZ')
2022 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2024 'name': 'qemu-fuzz-' + target_name,
2026 'sources': specific_fuzz.sources(),
2027 'dependencies': specific_fuzz.dependencies(),
2032 'name': 'qemu-' + target_name,
2039 emulators += {exe['name']:
2040 executable(exe['name'], exe['sources'],
2043 dependencies: arch_deps + deps + exe['dependencies'],
2044 objects: lib.extract_all_objects(recursive: true),
2045 link_language: link_language,
2046 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2047 link_args: link_args,
2048 gui_app: exe['gui'])
2051 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2053 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2054 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2055 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2056 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2058 custom_target(exe['name'] + stp['ext'],
2059 input: trace_events_all,
2060 output: exe['name'] + stp['ext'],
2062 install: stp['install'],
2063 install_dir: get_option('datadir') / 'systemtap/tapset',
2065 tracetool, '--group=all', '--format=' + stp['fmt'],
2066 '--binary=' + stp['bin'],
2067 '--target-name=' + target_name,
2068 '--target-type=' + target_type,
2069 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2077 # Other build targets
2079 if 'CONFIG_PLUGIN' in config_host
2080 install_headers('include/qemu/qemu-plugin.h')
2083 if 'CONFIG_GUEST_AGENT' in config_host
2087 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2088 # when we don't build tools or system
2089 if xkbcommon.found()
2090 # used for the update-keymaps target, so include rules even if !have_tools
2091 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2092 dependencies: [qemuutil, xkbcommon], install: have_tools)
2096 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2097 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2098 qemu_io = executable('qemu-io', files('qemu-io.c'),
2099 dependencies: [block, qemuutil], install: true)
2100 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2101 dependencies: [blockdev, qemuutil], install: true)
2103 subdir('storage-daemon')
2104 subdir('contrib/rdmacm-mux')
2105 subdir('contrib/elf2dmp')
2107 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2108 dependencies: qemuutil,
2111 if 'CONFIG_VHOST_USER' in config_host
2112 subdir('contrib/vhost-user-blk')
2113 subdir('contrib/vhost-user-gpu')
2114 subdir('contrib/vhost-user-input')
2115 subdir('contrib/vhost-user-scsi')
2118 if targetos == 'linux'
2119 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2120 dependencies: [qemuutil, libcap_ng],
2122 install_dir: get_option('libexecdir'))
2124 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2125 dependencies: [authz, crypto, io, qom, qemuutil,
2126 libcap_ng, mpathpersist],
2130 if 'CONFIG_IVSHMEM' in config_host
2131 subdir('contrib/ivshmem-client')
2132 subdir('contrib/ivshmem-server')
2141 if 'CONFIG_GTK' in config_host
2145 if host_machine.system() == 'windows'
2147 find_program('scripts/nsis.py'),
2149 get_option('prefix'),
2150 meson.current_source_dir(),
2153 '-DDISPLAYVERSION=' + meson.project_version(),
2156 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2158 if 'CONFIG_GTK' in config_host
2159 nsis_cmd += '-DCONFIG_GTK=y'
2162 nsis = custom_target('nsis',
2163 output: 'qemu-setup-' + meson.project_version() + '.exe',
2164 input: files('qemu.nsi'),
2165 build_always_stale: true,
2166 command: nsis_cmd + ['@INPUT@'])
2167 alias_target('installer', nsis)
2170 #########################
2171 # Configuration summary #
2172 #########################
2175 summary_info += {'Install prefix': get_option('prefix')}
2176 summary_info += {'BIOS directory': qemu_datadir}
2177 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2178 summary_info += {'binary directory': get_option('bindir')}
2179 summary_info += {'library directory': get_option('libdir')}
2180 summary_info += {'module directory': qemu_moddir}
2181 summary_info += {'libexec directory': get_option('libexecdir')}
2182 summary_info += {'include directory': get_option('includedir')}
2183 summary_info += {'config directory': get_option('sysconfdir')}
2184 if targetos != 'windows'
2185 summary_info += {'local state directory': get_option('localstatedir')}
2186 summary_info += {'Manual directory': get_option('mandir')}
2188 summary_info += {'local state directory': 'queried at runtime'}
2190 summary_info += {'Doc directory': get_option('docdir')}
2191 summary_info += {'Build directory': meson.current_build_dir()}
2192 summary_info += {'Source path': meson.current_source_dir()}
2193 summary_info += {'GIT binary': config_host['GIT']}
2194 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2195 summary_info += {'C compiler': meson.get_compiler('c').cmd_array()[0]}
2196 summary_info += {'Host C compiler': meson.get_compiler('c', native: true).cmd_array()[0]}
2197 if link_language == 'cpp'
2198 summary_info += {'C++ compiler': meson.get_compiler('cpp').cmd_array()[0]}
2200 summary_info += {'C++ compiler': false}
2202 if targetos == 'darwin'
2203 summary_info += {'Objective-C compiler': meson.get_compiler('objc').cmd_array()[0]}
2205 summary_info += {'ARFLAGS': config_host['ARFLAGS']}
2206 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
2207 + ['-O' + get_option('optimization')]
2208 + (get_option('debug') ? ['-g'] : []))}
2209 if link_language == 'cpp'
2210 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
2211 + ['-O' + get_option('optimization')]
2212 + (get_option('debug') ? ['-g'] : []))}
2214 link_args = get_option(link_language + '_link_args')
2215 if link_args.length() > 0
2216 summary_info += {'LDFLAGS': ' '.join(link_args)}
2218 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
2219 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
2220 summary_info += {'make': config_host['MAKE']}
2221 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2222 summary_info += {'sphinx-build': sphinx_build.found()}
2223 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2224 # TODO: add back version
2225 summary_info += {'slirp support': slirp_opt == 'disabled' ? false : slirp_opt}
2226 if slirp_opt != 'disabled'
2227 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2229 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
2230 if config_host.has_key('CONFIG_MODULES')
2231 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
2233 summary_info += {'host CPU': cpu}
2234 summary_info += {'host endianness': build_machine.endian()}
2235 summary_info += {'target list': ' '.join(target_dirs)}
2236 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
2237 summary_info += {'sparse enabled': sparse.found()}
2238 summary_info += {'strip binaries': get_option('strip')}
2239 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
2240 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
2241 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
2242 if targetos == 'darwin'
2243 summary_info += {'Cocoa support': config_host.has_key('CONFIG_COCOA')}
2245 # TODO: add back version
2246 summary_info += {'SDL support': sdl.found()}
2247 summary_info += {'SDL image support': sdl_image.found()}
2248 # TODO: add back version
2249 summary_info += {'GTK support': config_host.has_key('CONFIG_GTK')}
2250 summary_info += {'GTK GL support': config_host.has_key('CONFIG_GTK_GL')}
2251 summary_info += {'pixman': pixman.found()}
2252 # TODO: add back version
2253 summary_info += {'VTE support': config_host.has_key('CONFIG_VTE')}
2254 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
2255 summary_info += {'GNUTLS support': config_host.has_key('CONFIG_GNUTLS')}
2256 # TODO: add back version
2257 summary_info += {'libgcrypt': config_host.has_key('CONFIG_GCRYPT')}
2258 if config_host.has_key('CONFIG_GCRYPT')
2259 summary_info += {' hmac': config_host.has_key('CONFIG_GCRYPT_HMAC')}
2260 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2262 # TODO: add back version
2263 summary_info += {'nettle': config_host.has_key('CONFIG_NETTLE')}
2264 if config_host.has_key('CONFIG_NETTLE')
2265 summary_info += {' XTS': not config_host.has_key('CONFIG_QEMU_PRIVATE_XTS')}
2267 summary_info += {'libtasn1': config_host.has_key('CONFIG_TASN1')}
2268 summary_info += {'PAM': config_host.has_key('CONFIG_AUTH_PAM')}
2269 summary_info += {'iconv support': iconv.found()}
2270 summary_info += {'curses support': curses.found()}
2271 # TODO: add back version
2272 summary_info += {'virgl support': config_host.has_key('CONFIG_VIRGL')}
2273 summary_info += {'curl support': curl.found()}
2274 summary_info += {'mingw32 support': targetos == 'windows'}
2275 summary_info += {'Audio drivers': config_host['CONFIG_AUDIO_DRIVERS']}
2276 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
2277 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
2278 summary_info += {'VirtFS support': config_host.has_key('CONFIG_VIRTFS')}
2279 summary_info += {'build virtiofs daemon': have_virtiofsd}
2280 summary_info += {'Multipath support': mpathpersist.found()}
2281 summary_info += {'VNC support': vnc.found()}
2283 summary_info += {'VNC SASL support': sasl.found()}
2284 summary_info += {'VNC JPEG support': jpeg.found()}
2285 summary_info += {'VNC PNG support': png.found()}
2287 summary_info += {'xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
2288 if config_host.has_key('CONFIG_XEN_BACKEND')
2289 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
2291 summary_info += {'brlapi support': brlapi.found()}
2292 summary_info += {'Documentation': build_docs}
2293 summary_info += {'PIE': get_option('b_pie')}
2294 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
2295 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
2296 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
2297 summary_info += {'Linux io_uring support': config_host.has_key('CONFIG_LINUX_IO_URING')}
2298 summary_info += {'ATTR/XATTR support': config_host.has_key('CONFIG_ATTR')}
2299 summary_info += {'Install blobs': get_option('install_blobs')}
2300 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
2301 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
2302 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
2303 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
2304 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
2305 if config_all.has_key('CONFIG_TCG')
2306 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
2307 summary_info += {'TCG interpreter': config_host.has_key('CONFIG_TCG_INTERPRETER')}
2309 summary_info += {'malloc trim support': has_malloc_trim}
2310 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
2311 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
2312 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
2313 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
2314 summary_info += {'preadv support': config_host.has_key('CONFIG_PREADV')}
2315 summary_info += {'fdatasync': config_host.has_key('CONFIG_FDATASYNC')}
2316 summary_info += {'madvise': config_host.has_key('CONFIG_MADVISE')}
2317 summary_info += {'posix_madvise': config_host.has_key('CONFIG_POSIX_MADVISE')}
2318 summary_info += {'posix_memalign': config_host.has_key('CONFIG_POSIX_MEMALIGN')}
2319 summary_info += {'libcap-ng support': config_host.has_key('CONFIG_LIBCAP_NG')}
2320 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
2321 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
2322 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
2323 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
2324 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
2325 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
2326 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
2327 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
2328 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
2329 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
2330 if config_host['TRACE_BACKENDS'].split().contains('simple')
2331 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
2333 # TODO: add back protocol and server version
2334 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
2335 summary_info += {'rbd support': rbd.found()}
2336 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
2337 summary_info += {'smartcard support': config_host.has_key('CONFIG_SMARTCARD')}
2338 summary_info += {'U2F support': u2f.found()}
2339 summary_info += {'libusb': config_host.has_key('CONFIG_USB_LIBUSB')}
2340 summary_info += {'usb net redir': config_host.has_key('CONFIG_USB_REDIR')}
2341 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
2342 summary_info += {'OpenGL dmabufs': config_host.has_key('CONFIG_OPENGL_DMABUF')}
2343 summary_info += {'libiscsi support': libiscsi.found()}
2344 summary_info += {'libnfs support': libnfs.found()}
2345 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
2346 if targetos == 'windows'
2347 if 'WIN_SDK' in config_host
2348 summary_info += {'Windows SDK': config_host['WIN_SDK']}
2350 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
2351 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
2352 summary_info += {'QGA MSI support': config_host.has_key('CONFIG_QGA_MSI')}
2354 summary_info += {'seccomp support': config_host.has_key('CONFIG_SECCOMP')}
2355 summary_info += {'CFI support': get_option('cfi')}
2356 summary_info += {'CFI debug support': get_option('cfi_debug')}
2357 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
2358 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
2359 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
2360 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
2361 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
2362 summary_info += {'GlusterFS support': glusterfs.found()}
2363 summary_info += {'gcov': get_option('b_coverage')}
2364 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
2365 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
2366 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
2367 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
2368 summary_info += {'lzo support': lzo.found()}
2369 summary_info += {'snappy support': snappy.found()}
2370 summary_info += {'bzip2 support': libbzip2.found()}
2371 summary_info += {'lzfse support': config_host.has_key('CONFIG_LZFSE')}
2372 summary_info += {'zstd support': config_host.has_key('CONFIG_ZSTD')}
2373 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
2374 summary_info += {'libxml2': config_host.has_key('CONFIG_LIBXML2')}
2375 summary_info += {'memory allocator': get_option('malloc')}
2376 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
2377 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
2378 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
2379 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
2380 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
2381 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
2382 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
2383 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
2384 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
2385 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
2386 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
2387 summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
2388 summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
2389 summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
2390 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
2391 summary_info += {'libudev': libudev.found()}
2392 summary_info += {'default devices': config_host['CONFIG_MINIKCONF_MODE'] == '--defconfig'}
2393 summary_info += {'plugin support': config_host.has_key('CONFIG_PLUGIN')}
2394 summary_info += {'fuzzing support': config_host.has_key('CONFIG_FUZZ')}
2395 if config_host.has_key('HAVE_GDB_BIN')
2396 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2398 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
2399 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
2400 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
2401 summary_info += {'FUSE exports': fuse.found()}
2402 summary_info += {'FUSE lseek': fuse_lseek.found()}
2403 summary(summary_info, bool_yn: true)
2405 if not supported_cpus.contains(cpu)
2407 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
2409 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
2410 message('The QEMU project intends to remove support for this host CPU in')
2411 message('a future release if nobody volunteers to maintain it and to')
2412 message('provide a build host for our continuous integration setup.')
2413 message('configure has succeeded and you can continue to build, but')
2414 message('if you care about QEMU on this platform you should contact')
2415 message('us upstream at qemu-devel@nongnu.org.')
2418 if not supported_oses.contains(targetos)
2420 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
2422 message('Host OS ' + targetos + 'support is not currently maintained.')
2423 message('The QEMU project intends to remove support for this host OS in')
2424 message('a future release if nobody volunteers to maintain it and to')
2425 message('provide a build host for our continuous integration setup.')
2426 message('configure has succeeded and you can continue to build, but')
2427 message('if you care about QEMU on this platform you should contact')
2428 message('us upstream at qemu-devel@nongnu.org.')