1 project('qemu', ['c'], meson_version: '>=0.58.2',
2 default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
4 version: files('VERSION'))
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
11 sh = find_program('sh')
12 cc = meson.get_compiler('c')
13 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
14 enable_modules = 'CONFIG_MODULES' in config_host
15 enable_static = 'CONFIG_STATIC' in config_host
17 # Allow both shared and static libraries unless --enable-static
18 static_kwargs = enable_static ? {'static': true} : {}
20 # Temporary directory used for files created while
21 # configure runs. Since it is in the build directory
22 # we can safely blow away any previous version of it
23 # (and we need not jump through hoops to try to delete
24 # it when configure exits.)
25 tmpdir = meson.current_build_dir() / 'meson-private/temp'
27 if get_option('qemu_suffix').startswith('/')
28 error('qemu_suffix cannot start with a /')
31 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
32 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
33 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
34 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
36 qemu_desktopdir = get_option('datadir') / 'applications'
37 qemu_icondir = get_option('datadir') / 'icons'
39 config_host_data = configuration_data()
42 target_dirs = config_host['TARGET_DIRS'].split()
45 foreach target : target_dirs
46 have_user = have_user or target.endswith('-user')
47 have_system = have_system or target.endswith('-softmmu')
49 have_tools = 'CONFIG_TOOLS' in config_host
50 have_block = have_system or have_tools
52 python = import('python').find_installation()
54 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
55 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
56 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
58 cpu = host_machine.cpu_family()
59 targetos = host_machine.system()
61 if cpu in ['x86', 'x86_64']
62 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
64 kvm_targets = ['aarch64-softmmu']
66 kvm_targets = ['s390x-softmmu']
67 elif cpu in ['ppc', 'ppc64']
68 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
69 elif cpu in ['mips', 'mips64']
70 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
75 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
78 accelerator_targets += {
79 'CONFIG_HVF': ['aarch64-softmmu']
83 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
84 # i386 emulator provides xenpv machine type for multiple architectures
85 accelerator_targets += {
86 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
89 if cpu in ['x86', 'x86_64']
90 accelerator_targets += {
91 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
92 'CONFIG_HVF': ['x86_64-softmmu'],
93 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
94 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
99 # Darwin does not support references to thread-local variables in modules
100 if targetos != 'darwin'
101 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
104 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
105 unpack_edk2_blobs = false
106 foreach target : edk2_targets
107 if target in target_dirs
108 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
109 unpack_edk2_blobs = bzip2.found()
118 # Specify linker-script with add_project_link_arguments so that it is not placed
119 # within a linker --start-group/--end-group pair
120 if get_option('fuzzing')
121 add_project_link_arguments(['-Wl,-T,',
122 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
123 native: false, language: ['c', 'cpp', 'objc'])
125 # Specify a filter to only instrument code that is directly related to
127 configure_file(output: 'instrumentation-filter',
128 input: 'scripts/oss-fuzz/instrumentation-filter-template',
130 add_global_arguments(
131 cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
132 native: false, language: ['c', 'cpp', 'objc'])
134 if get_option('fuzzing_engine') == ''
135 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
136 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
137 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
138 # unable to bind the fuzzer-related callbacks added by instrumentation.
139 add_global_arguments('-fsanitize=fuzzer-no-link',
140 native: false, language: ['c', 'cpp', 'objc'])
141 add_global_link_arguments('-fsanitize=fuzzer-no-link',
142 native: false, language: ['c', 'cpp', 'objc'])
143 # For the actual fuzzer binaries, we need to link against the libfuzzer
144 # library. They need to be configurable, to support OSS-Fuzz
145 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
147 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
148 # the needed CFLAGS have already been provided
149 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
153 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
154 native: false, language: ['c', 'objc'])
155 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
156 native: false, language: 'cpp')
157 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
158 native: false, language: ['c', 'cpp', 'objc'])
160 if targetos == 'linux'
161 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
162 '-isystem', 'linux-headers',
163 language: ['c', 'cpp'])
166 add_project_arguments('-iquote', '.',
167 '-iquote', meson.current_source_dir(),
168 '-iquote', meson.current_source_dir() / 'include',
169 '-iquote', meson.current_source_dir() / 'disas/libvixl',
170 language: ['c', 'cpp', 'objc'])
172 link_language = meson.get_external_property('link_language', 'cpp')
173 if link_language == 'cpp'
174 add_languages('cpp', required: true, native: false)
176 if host_machine.system() == 'darwin'
177 add_languages('objc', required: false, native: false)
180 sparse = find_program('cgcc', required: get_option('sparse'))
183 command: [find_program('scripts/check_sparse.py'),
184 'compile_commands.json', sparse.full_path(), '-Wbitwise',
185 '-Wno-transparent-union', '-Wno-old-initializer',
186 '-Wno-non-pointer-null'])
189 ###########################################
190 # Target-specific checks and dependencies #
191 ###########################################
193 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
196 #include <sys/types.h>
197 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
198 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
200 args: ['-Werror', '-fsanitize=fuzzer'])
201 error('Your compiler does not support -fsanitize=fuzzer')
204 if targetos != 'linux' and get_option('mpath').enabled()
205 error('Multipath is supported only on Linux')
208 if targetos != 'linux' and get_option('multiprocess').enabled()
209 error('Multiprocess QEMU is supported only on Linux')
211 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
213 libm = cc.find_library('m', required: false)
214 threads = dependency('threads')
215 util = cc.find_library('util', required: false)
221 emulator_link_args = []
224 if targetos == 'windows'
225 socket = cc.find_library('ws2_32')
226 winmm = cc.find_library('winmm')
228 win = import('windows')
229 version_res = win.compile_resources('version.rc',
230 depend_files: files('pc-bios/qemu-nsis.ico'),
231 include_directories: include_directories('.'))
232 elif targetos == 'darwin'
233 coref = dependency('appleframeworks', modules: 'CoreFoundation')
234 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
235 elif targetos == 'sunos'
236 socket = [cc.find_library('socket'),
237 cc.find_library('nsl'),
238 cc.find_library('resolv')]
239 elif targetos == 'haiku'
240 socket = [cc.find_library('posix_error_mapper'),
241 cc.find_library('network'),
242 cc.find_library('bsd')]
243 elif targetos == 'openbsd'
244 if not get_option('tcg').disabled() and target_dirs.length() > 0
245 # Disable OpenBSD W^X if available
246 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
251 if not get_option('kvm').disabled() and targetos == 'linux'
252 accelerators += 'CONFIG_KVM'
254 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
255 accelerators += 'CONFIG_XEN'
256 have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
258 have_xen_pci_passthrough = false
260 if not get_option('whpx').disabled() and targetos == 'windows'
261 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
262 error('WHPX requires 64-bit host')
263 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
264 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
265 accelerators += 'CONFIG_WHPX'
268 if not get_option('hvf').disabled()
269 hvf = dependency('appleframeworks', modules: 'Hypervisor',
270 required: get_option('hvf'))
272 accelerators += 'CONFIG_HVF'
275 if not get_option('hax').disabled()
276 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
277 accelerators += 'CONFIG_HAX'
280 if targetos == 'netbsd'
281 if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
282 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
285 accelerators += 'CONFIG_NVMM'
289 tcg_arch = config_host['ARCH']
290 if not get_option('tcg').disabled()
291 if cpu not in supported_cpus
292 if get_option('tcg_interpreter')
293 warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
295 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
297 elif get_option('tcg_interpreter')
298 warning('Use of the TCG interpretor is not recommended on this host')
299 warning('architecture. There is a native TCG execution backend available')
300 warning('which provides substantially better performance and reliability.')
301 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
302 warning('configuration option on this architecture to use the native')
305 if get_option('tcg_interpreter')
307 elif config_host['ARCH'] == 'sparc64'
309 elif config_host['ARCH'] in ['x86_64', 'x32']
311 elif config_host['ARCH'] == 'ppc64'
313 elif config_host['ARCH'] in ['riscv32', 'riscv64']
316 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
317 language: ['c', 'cpp', 'objc'])
319 accelerators += 'CONFIG_TCG'
320 config_host += { 'CONFIG_TCG': 'y' }
323 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
324 error('KVM not available on this platform')
326 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
327 error('HVF not available on this platform')
329 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
330 error('NVMM not available on this platform')
332 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
333 error('WHPX not available on this platform')
335 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
336 if 'CONFIG_XEN' in accelerators
337 error('Xen PCI passthrough not available on this platform')
339 error('Xen PCI passthrough requested but Xen not enabled')
347 # The path to glib.h is added to all compilation commands. This was
348 # grandfathered in from the QEMU Makefiles.
349 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
350 native: false, language: ['c', 'cpp', 'objc'])
351 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
352 link_args: config_host['GLIB_LIBS'].split())
353 # override glib dep with the configure results (for subprojects)
354 meson.override_dependency('glib-2.0', glib)
357 if 'CONFIG_GIO' in config_host
358 gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
359 link_args: config_host['GIO_LIBS'].split())
362 if 'CONFIG_TRACE_UST' in config_host
363 lttng = declare_dependency(link_args: config_host['LTTNG_UST_LIBS'].split())
366 if have_system or have_tools
367 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
368 method: 'pkg-config', kwargs: static_kwargs)
370 libaio = cc.find_library('aio', required: false)
371 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
373 linux_io_uring = not_found
374 if not get_option('linux_io_uring').auto() or have_block
375 linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
376 method: 'pkg-config', kwargs: static_kwargs)
379 if not get_option('libxml2').auto() or have_block
380 libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
381 method: 'pkg-config', kwargs: static_kwargs)
384 if not get_option('libnfs').auto() or have_block
385 libnfs = dependency('libnfs', version: '>=1.9.3',
386 required: get_option('libnfs'),
387 method: 'pkg-config', kwargs: static_kwargs)
392 #include <sys/types.h>
393 #ifdef CONFIG_LIBATTR
394 #include <attr/xattr.h>
396 #include <sys/xattr.h>
398 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
401 have_old_libattr = false
402 if not get_option('attr').disabled()
403 if cc.links(libattr_test)
404 libattr = declare_dependency()
406 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
407 required: get_option('attr'),
408 kwargs: static_kwargs)
409 if libattr.found() and not \
410 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
412 if get_option('attr').enabled()
413 error('could not link libattr')
415 warning('could not link libattr, disabling')
418 have_old_libattr = libattr.found()
423 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
424 if cocoa.found() and get_option('sdl').enabled()
425 error('Cocoa and SDL cannot be enabled at the same time')
427 if cocoa.found() and get_option('gtk').enabled()
428 error('Cocoa and GTK+ cannot be enabled at the same time')
432 if not get_option('seccomp').auto() or have_system or have_tools
433 seccomp = dependency('libseccomp', version: '>=2.3.0',
434 required: get_option('seccomp'),
435 method: 'pkg-config', kwargs: static_kwargs)
438 libcap_ng = not_found
439 if not get_option('cap_ng').auto() or have_system or have_tools
440 libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
441 required: get_option('cap_ng'),
442 kwargs: static_kwargs)
444 if libcap_ng.found() and not cc.links('''
448 capng_capability_to_name(CAPNG_EFFECTIVE);
450 }''', dependencies: libcap_ng)
451 libcap_ng = not_found
452 if get_option('cap_ng').enabled()
453 error('could not link libcap-ng')
455 warning('could not link libcap-ng, disabling')
459 if get_option('xkbcommon').auto() and not have_system and not have_tools
460 xkbcommon = not_found
462 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
463 method: 'pkg-config', kwargs: static_kwargs)
466 if config_host.has_key('CONFIG_VDE')
467 vde = declare_dependency(link_args: config_host['VDE_LIBS'].split())
471 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
472 pulse = dependency('libpulse', required: get_option('pa'),
473 method: 'pkg-config', kwargs: static_kwargs)
476 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
477 alsa = dependency('alsa', required: get_option('alsa'),
478 method: 'pkg-config', kwargs: static_kwargs)
481 if not get_option('jack').auto() or have_system
482 jack = dependency('jack', required: get_option('jack'),
483 method: 'pkg-config', kwargs: static_kwargs)
487 spice_headers = not_found
488 spice_protocol = not_found
489 if 'CONFIG_SPICE' in config_host
490 spice = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split(),
491 link_args: config_host['SPICE_LIBS'].split())
492 spice_headers = declare_dependency(compile_args: config_host['SPICE_CFLAGS'].split())
494 if 'CONFIG_SPICE_PROTOCOL' in config_host
495 spice_protocol = declare_dependency(compile_args: config_host['SPICE_PROTOCOL_CFLAGS'].split())
497 rt = cc.find_library('rt', required: false)
499 if 'CONFIG_PLUGIN' in config_host
500 libdl = cc.find_library('dl', required: false)
501 if not cc.has_function('dlopen', dependencies: libdl)
502 error('dlopen not found')
506 if not get_option('libiscsi').auto() or have_block
507 libiscsi = dependency('libiscsi', version: '>=1.9.0',
508 required: get_option('libiscsi'),
509 method: 'pkg-config', kwargs: static_kwargs)
512 if not get_option('zstd').auto() or have_block
513 zstd = dependency('libzstd', version: '>=1.4.0',
514 required: get_option('zstd'),
515 method: 'pkg-config', kwargs: static_kwargs)
518 if not get_option('virglrenderer').auto() or have_system
519 virgl = dependency('virglrenderer',
520 method: 'pkg-config',
521 required: get_option('virglrenderer'),
522 kwargs: static_kwargs)
525 if not get_option('curl').auto() or have_block
526 curl = dependency('libcurl', version: '>=7.29.0',
527 method: 'pkg-config',
528 required: get_option('curl'),
529 kwargs: static_kwargs)
532 if targetos == 'linux' and (have_system or have_tools)
533 libudev = dependency('libudev',
534 method: 'pkg-config',
535 required: get_option('libudev'),
536 kwargs: static_kwargs)
539 mpathlibs = [libudev]
540 mpathpersist = not_found
541 mpathpersist_new_api = false
542 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
543 mpath_test_source_new = '''
545 #include <mpath_persist.h>
546 unsigned mpath_mx_alloc_len = 1024;
548 static struct config *multipath_conf;
549 extern struct udev *udev;
550 extern struct config *get_multipath_config(void);
551 extern void put_multipath_config(struct config *conf);
553 struct config *get_multipath_config(void) { return multipath_conf; }
554 void put_multipath_config(struct config *conf) { }
557 multipath_conf = mpath_lib_init();
560 mpath_test_source_old = '''
562 #include <mpath_persist.h>
563 unsigned mpath_mx_alloc_len = 1024;
566 struct udev *udev = udev_new();
567 mpath_lib_init(udev);
570 libmpathpersist = cc.find_library('mpathpersist',
571 required: get_option('mpath'),
572 kwargs: static_kwargs)
573 if libmpathpersist.found()
574 mpathlibs += libmpathpersist
576 mpathlibs += cc.find_library('devmapper',
577 required: get_option('mpath'),
578 kwargs: static_kwargs)
580 mpathlibs += cc.find_library('multipath',
581 required: get_option('mpath'),
582 kwargs: static_kwargs)
583 foreach lib: mpathlibs
589 if mpathlibs.length() == 0
590 msg = 'Dependencies missing for libmpathpersist'
591 elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
592 mpathpersist = declare_dependency(dependencies: mpathlibs)
593 mpathpersist_new_api = true
594 elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
595 mpathpersist = declare_dependency(dependencies: mpathlibs)
597 msg = 'Cannot detect libmpathpersist API'
599 if not mpathpersist.found()
600 if get_option('mpath').enabled()
603 warning(msg + ', disabling')
611 if have_system and not get_option('curses').disabled()
618 setlocale(LC_ALL, "");
620 addwstr(L"wide chars\n");
622 add_wch(WACS_DEGREE);
626 curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
627 foreach curses_dep : curses_dep_list
628 if not curses.found()
629 curses = dependency(curses_dep,
631 method: 'pkg-config',
632 kwargs: static_kwargs)
635 msg = get_option('curses').enabled() ? 'curses library not found' : ''
636 curses_compile_args = ['-DNCURSES_WIDECHAR']
638 if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
639 curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
641 msg = 'curses package not usable'
645 if not curses.found()
646 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
647 if targetos != 'windows' and not has_curses_h
648 message('Trying with /usr/include/ncursesw')
649 curses_compile_args += ['-I/usr/include/ncursesw']
650 has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
653 curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
654 foreach curses_libname : curses_libname_list
655 libcurses = cc.find_library(curses_libname,
657 kwargs: static_kwargs)
659 if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
660 curses = declare_dependency(compile_args: curses_compile_args,
661 dependencies: [libcurses])
664 msg = 'curses library not usable'
670 if not get_option('iconv').disabled()
671 foreach link_args : [ ['-liconv'], [] ]
672 # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
673 # We need to use libiconv if available because mixing libiconv's headers with
674 # the system libc does not work.
675 # However, without adding glib to the dependencies -L/usr/local/lib will not be
676 # included in the command line and libiconv will not be found.
680 iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
681 return conv != (iconv_t) -1;
682 }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
683 iconv = declare_dependency(link_args: link_args, dependencies: glib)
688 if curses.found() and not iconv.found()
689 if get_option('iconv').enabled()
690 error('iconv not available')
692 msg = 'iconv required for curses UI but not available'
695 if not curses.found() and msg != ''
696 if get_option('curses').enabled()
699 warning(msg + ', disabling')
705 if not get_option('brlapi').auto() or have_system
706 brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
707 required: get_option('brlapi'),
708 kwargs: static_kwargs)
709 if brlapi.found() and not cc.links('''
712 int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
714 if get_option('brlapi').enabled()
715 error('could not link brlapi')
717 warning('could not link brlapi, disabling')
723 if not get_option('sdl').auto() or (have_system and not cocoa.found())
724 sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
725 sdl_image = not_found
728 # work around 2.0.8 bug
729 sdl = declare_dependency(compile_args: '-Wno-undef',
731 sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
732 method: 'pkg-config', kwargs: static_kwargs)
734 if get_option('sdl_image').enabled()
735 error('sdl-image required, but SDL was @0@'.format(
736 get_option('sdl').disabled() ? 'disabled' : 'not found'))
738 sdl_image = not_found
742 if not get_option('rbd').auto() or have_block
743 librados = cc.find_library('rados', required: get_option('rbd'),
744 kwargs: static_kwargs)
745 librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
746 required: get_option('rbd'),
747 kwargs: static_kwargs)
748 if librados.found() and librbd.found()
751 #include <rbd/librbd.h>
754 rados_create(&cluster, NULL);
755 #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
759 }''', dependencies: [librbd, librados])
760 rbd = declare_dependency(dependencies: [librbd, librados])
761 elif get_option('rbd').enabled()
762 error('librbd >= 1.12.0 required')
764 warning('librbd >= 1.12.0 not found, disabling')
769 glusterfs = not_found
770 glusterfs_ftruncate_has_stat = false
771 glusterfs_iocb_has_stat = false
772 if not get_option('glusterfs').auto() or have_block
773 glusterfs = dependency('glusterfs-api', version: '>=3',
774 required: get_option('glusterfs'),
775 method: 'pkg-config', kwargs: static_kwargs)
777 glusterfs_ftruncate_has_stat = cc.links('''
778 #include <glusterfs/api/glfs.h>
783 /* new glfs_ftruncate() passes two additional args */
784 return glfs_ftruncate(NULL, 0, NULL, NULL);
786 ''', dependencies: glusterfs)
787 glusterfs_iocb_has_stat = cc.links('''
788 #include <glusterfs/api/glfs.h>
790 /* new glfs_io_cbk() passes two additional glfs_stat structs */
792 glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
798 glfs_io_cbk iocb = &glusterfs_iocb;
799 iocb(NULL, 0 , NULL, NULL, NULL);
802 ''', dependencies: glusterfs)
806 if 'CONFIG_LIBSSH' in config_host
807 libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
808 link_args: config_host['LIBSSH_LIBS'].split())
811 if not get_option('bzip2').auto() or have_block
812 libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
813 required: get_option('bzip2'),
814 kwargs: static_kwargs)
815 if libbzip2.found() and not cc.links('''
817 int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
819 if get_option('bzip2').enabled()
820 error('could not link libbzip2')
822 warning('could not link libbzip2, disabling')
828 if not get_option('lzfse').auto() or have_block
829 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
830 required: get_option('lzfse'),
831 kwargs: static_kwargs)
833 if liblzfse.found() and not cc.links('''
835 int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
837 if get_option('lzfse').enabled()
838 error('could not link liblzfse')
840 warning('could not link liblzfse, disabling')
845 if not get_option('oss').auto() or have_system
846 if not cc.has_header('sys/soundcard.h')
848 elif targetos == 'netbsd'
849 oss = cc.find_library('ossaudio', required: get_option('oss'),
850 kwargs: static_kwargs)
852 oss = declare_dependency()
856 if get_option('oss').enabled()
857 error('OSS not found')
859 warning('OSS not found, disabling')
864 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
865 if cc.has_header('dsound.h')
866 dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
869 if not dsound.found()
870 if get_option('dsound').enabled()
871 error('DirectSound not found')
873 warning('DirectSound not found, disabling')
878 coreaudio = not_found
879 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
880 coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
881 required: get_option('coreaudio'))
882 if coreaudio.found() and not cc.links('''
883 #include <CoreAudio/CoreAudio.h>
886 return (int)AudioGetCurrentHostTime();
888 coreaudio = not_found
891 if not coreaudio.found()
892 if get_option('coreaudio').enabled()
893 error('CoreAudio not found')
895 warning('CoreAudio not found, disabling')
901 if 'CONFIG_OPENGL' in config_host
902 opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
903 link_args: config_host['OPENGL_LIBS'].split())
906 if (have_system or have_tools) and (virgl.found() or opengl.found())
907 gbm = dependency('gbm', method: 'pkg-config', required: false,
908 kwargs: static_kwargs)
912 gnutls_crypto = not_found
913 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
914 # For general TLS support our min gnutls matches
915 # that implied by our platform support matrix
917 # For the crypto backends, we look for a newer
920 # Version 3.6.8 is needed to get XTS
921 # Version 3.6.13 is needed to get PBKDF
922 # Version 3.6.14 is needed to get HW accelerated XTS
924 # If newer enough gnutls isn't available, we can
925 # still use a different crypto backend to satisfy
926 # the platform support requirements
927 gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
928 method: 'pkg-config',
930 kwargs: static_kwargs)
931 if gnutls_crypto.found()
932 gnutls = gnutls_crypto
934 # Our min version if all we need is TLS
935 gnutls = dependency('gnutls', version: '>=3.5.18',
936 method: 'pkg-config',
937 required: get_option('gnutls'),
938 kwargs: static_kwargs)
942 # We prefer use of gnutls for crypto, unless the options
943 # explicitly asked for nettle or gcrypt.
945 # If gnutls isn't available for crypto, then we'll prefer
946 # gcrypt over nettle for performance reasons.
951 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
952 error('Only one of gcrypt & nettle can be enabled')
955 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
956 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
957 gnutls_crypto = not_found
960 if not gnutls_crypto.found()
961 if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
962 gcrypt = dependency('libgcrypt', version: '>=1.8',
963 method: 'config-tool',
964 required: get_option('gcrypt'),
965 kwargs: static_kwargs)
966 # Debian has removed -lgpg-error from libgcrypt-config
967 # as it "spreads unnecessary dependencies" which in
968 # turn breaks static builds...
969 if gcrypt.found() and enable_static
970 gcrypt = declare_dependency(dependencies: [
972 cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
975 if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
976 nettle = dependency('nettle', version: '>=3.4',
977 method: 'pkg-config',
978 required: get_option('nettle'),
979 kwargs: static_kwargs)
980 if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
989 if not get_option('gtk').auto() or (have_system and not cocoa.found())
990 gtk = dependency('gtk+-3.0', version: '>=3.22.0',
991 method: 'pkg-config',
992 required: get_option('gtk'),
993 kwargs: static_kwargs)
995 gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
996 method: 'pkg-config',
998 kwargs: static_kwargs)
999 gtk = declare_dependency(dependencies: [gtk, gtkx11])
1001 if not get_option('vte').auto() or have_system
1002 vte = dependency('vte-2.91',
1003 method: 'pkg-config',
1004 required: get_option('vte'),
1005 kwargs: static_kwargs)
1012 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1013 kwargs: static_kwargs)
1019 if have_system and not get_option('vnc').disabled()
1020 vnc = declare_dependency() # dummy dependency
1021 png = dependency('libpng', required: get_option('vnc_png'),
1022 method: 'pkg-config', kwargs: static_kwargs)
1023 jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1024 method: 'pkg-config', kwargs: static_kwargs)
1025 sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1026 required: get_option('vnc_sasl'),
1027 kwargs: static_kwargs)
1029 sasl = declare_dependency(dependencies: sasl,
1030 compile_args: '-DSTRUCT_IOVEC_DEFINED')
1035 if not get_option('auth_pam').auto() or have_system
1036 pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1037 required: get_option('auth_pam'),
1038 kwargs: static_kwargs)
1040 if pam.found() and not cc.links('''
1042 #include <security/pam_appl.h>
1044 const char *service_name = "qemu";
1045 const char *user = "frank";
1046 const struct pam_conv pam_conv = { 0 };
1047 pam_handle_t *pamh = NULL;
1048 pam_start(service_name, user, &pam_conv, &pamh);
1050 }''', dependencies: pam)
1052 if get_option('auth_pam').enabled()
1053 error('could not link libpam')
1055 warning('could not link libpam, disabling')
1060 if not get_option('snappy').auto() or have_system
1061 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1062 required: get_option('snappy'),
1063 kwargs: static_kwargs)
1065 if snappy.found() and not cc.links('''
1066 #include <snappy-c.h>
1067 int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1069 if get_option('snappy').enabled()
1070 error('could not link libsnappy')
1072 warning('could not link libsnappy, disabling')
1077 if not get_option('lzo').auto() or have_system
1078 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1079 required: get_option('lzo'),
1080 kwargs: static_kwargs)
1082 if lzo.found() and not cc.links('''
1083 #include <lzo/lzo1x.h>
1084 int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1086 if get_option('lzo').enabled()
1087 error('could not link liblzo2')
1089 warning('could not link liblzo2, disabling')
1094 if 'CONFIG_RDMA' in config_host
1095 rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1098 if 'CONFIG_NUMA' in config_host
1099 numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1102 if 'CONFIG_XEN_BACKEND' in config_host
1103 xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1104 link_args: config_host['XEN_LIBS'].split())
1107 if not get_option('smartcard').auto() or have_system
1108 cacard = dependency('libcacard', required: get_option('smartcard'),
1109 version: '>=2.5.1', method: 'pkg-config',
1110 kwargs: static_kwargs)
1114 u2f = dependency('u2f-emu', required: get_option('u2f'),
1115 method: 'pkg-config',
1116 kwargs: static_kwargs)
1118 usbredir = not_found
1119 if not get_option('usb_redir').auto() or have_system
1120 usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1121 version: '>=0.6', method: 'pkg-config',
1122 kwargs: static_kwargs)
1125 if not get_option('libusb').auto() or have_system
1126 libusb = dependency('libusb-1.0', required: get_option('libusb'),
1127 version: '>=1.0.13', method: 'pkg-config',
1128 kwargs: static_kwargs)
1132 if not get_option('libpmem').auto() or have_system
1133 libpmem = dependency('libpmem', required: get_option('libpmem'),
1134 method: 'pkg-config', kwargs: static_kwargs)
1136 libdaxctl = not_found
1137 if not get_option('libdaxctl').auto() or have_system
1138 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1139 version: '>=57', method: 'pkg-config',
1140 kwargs: static_kwargs)
1144 tasn1 = dependency('libtasn1',
1145 method: 'pkg-config',
1146 kwargs: static_kwargs)
1148 keyutils = dependency('libkeyutils', required: false,
1149 method: 'pkg-config', kwargs: static_kwargs)
1151 has_gettid = cc.has_function('gettid')
1156 if get_option('malloc') == 'system'
1158 not get_option('malloc_trim').disabled() and \
1159 cc.links('''#include <malloc.h>
1160 int main(void) { malloc_trim(0); return 0; }''')
1162 has_malloc_trim = false
1163 malloc = cc.find_library(get_option('malloc'), required: true)
1165 if not has_malloc_trim and get_option('malloc_trim').enabled()
1166 if get_option('malloc') == 'system'
1167 error('malloc_trim not available on this platform.')
1169 error('malloc_trim not available with non-libc memory allocator')
1173 # Check whether the glibc provides statx()
1175 gnu_source_prefix = '''
1180 statx_test = gnu_source_prefix + '''
1181 #include <sys/stat.h>
1183 struct statx statxbuf;
1184 statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1188 has_statx = cc.links(statx_test)
1190 have_vhost_user_blk_server = (targetos == 'linux' and
1191 'CONFIG_VHOST_USER' in config_host)
1193 if get_option('vhost_user_blk_server').enabled()
1194 if targetos != 'linux'
1195 error('vhost_user_blk_server requires linux')
1196 elif 'CONFIG_VHOST_USER' not in config_host
1197 error('vhost_user_blk_server requires vhost-user support')
1199 elif get_option('vhost_user_blk_server').disabled() or not have_system
1200 have_vhost_user_blk_server = false
1204 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1205 error('Cannot enable fuse-lseek while fuse is disabled')
1208 fuse = dependency('fuse3', required: get_option('fuse'),
1209 version: '>=3.1', method: 'pkg-config',
1210 kwargs: static_kwargs)
1212 fuse_lseek = not_found
1213 if not get_option('fuse_lseek').disabled()
1214 if fuse.version().version_compare('>=3.8')
1216 fuse_lseek = declare_dependency()
1217 elif get_option('fuse_lseek').enabled()
1219 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1221 error('fuse-lseek requires libfuse, which was not found')
1227 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1228 if libbpf.found() and not cc.links('''
1229 #include <bpf/libbpf.h>
1232 bpf_object__destroy_skeleton(NULL);
1234 }''', dependencies: libbpf)
1236 if get_option('bpf').enabled()
1237 error('libbpf skeleton test failed')
1239 warning('libbpf skeleton test failed, disabling')
1247 audio_drivers_selected = []
1249 audio_drivers_available = {
1250 'alsa': alsa.found(),
1251 'coreaudio': coreaudio.found(),
1252 'dsound': dsound.found(),
1253 'jack': jack.found(),
1255 'pa': pulse.found(),
1258 foreach k, v: audio_drivers_available
1259 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1262 # Default to native drivers first, OSS second, SDL third
1263 audio_drivers_priority = \
1264 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1265 (targetos == 'linux' ? [] : [ 'sdl' ])
1266 audio_drivers_default = []
1267 foreach k: audio_drivers_priority
1268 if audio_drivers_available[k]
1269 audio_drivers_default += k
1273 foreach k: get_option('audio_drv_list')
1275 audio_drivers_selected += audio_drivers_default
1276 elif not audio_drivers_available[k]
1277 error('Audio driver "@0@" not available.'.format(k))
1279 audio_drivers_selected += k
1283 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1284 '"' + '", "'.join(audio_drivers_selected) + '", ')
1286 if get_option('cfi')
1288 # Check for dependency on LTO
1289 if not get_option('b_lto')
1290 error('Selected Control-Flow Integrity but LTO is disabled')
1292 if config_host.has_key('CONFIG_MODULES')
1293 error('Selected Control-Flow Integrity is not compatible with modules')
1295 # Check for cfi flags. CFI requires LTO so we can't use
1296 # get_supported_arguments, but need a more complex "compiles" which allows
1298 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1299 args: ['-flto', '-fsanitize=cfi-icall'] )
1300 cfi_flags += '-fsanitize=cfi-icall'
1302 error('-fsanitize=cfi-icall is not supported by the compiler')
1304 if cc.compiles('int main () { return 0; }',
1305 name: '-fsanitize-cfi-icall-generalize-pointers',
1306 args: ['-flto', '-fsanitize=cfi-icall',
1307 '-fsanitize-cfi-icall-generalize-pointers'] )
1308 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1310 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1312 if get_option('cfi_debug')
1313 if cc.compiles('int main () { return 0; }',
1314 name: '-fno-sanitize-trap=cfi-icall',
1315 args: ['-flto', '-fsanitize=cfi-icall',
1316 '-fno-sanitize-trap=cfi-icall'] )
1317 cfi_flags += '-fno-sanitize-trap=cfi-icall'
1319 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1322 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1323 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1326 have_host_block_device = (targetos != 'darwin' or
1327 cc.has_header('IOKit/storage/IOMedia.h'))
1329 have_virtfs = (targetos == 'linux' and
1334 have_virtfs_proxy_helper = have_virtfs and have_tools
1336 if get_option('virtfs').enabled()
1338 if targetos != 'linux'
1339 error('virtio-9p (virtfs) requires Linux')
1340 elif not libcap_ng.found() or not libattr.found()
1341 error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1342 elif not have_system
1343 error('virtio-9p (virtfs) needs system emulation support')
1346 elif get_option('virtfs').disabled()
1350 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1351 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1352 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1353 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1354 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1355 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1356 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1357 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1358 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1359 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1360 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1361 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1363 config_host_data.set('CONFIG_ATTR', libattr.found())
1364 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1365 config_host_data.set('CONFIG_COCOA', cocoa.found())
1366 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1367 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1368 config_host_data.set('CONFIG_LZO', lzo.found())
1369 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1370 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1371 config_host_data.set('CONFIG_CURL', curl.found())
1372 config_host_data.set('CONFIG_CURSES', curses.found())
1373 config_host_data.set('CONFIG_GBM', gbm.found())
1374 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1375 if glusterfs.found()
1376 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1377 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1378 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1379 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1380 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1381 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1383 config_host_data.set('CONFIG_GTK', gtk.found())
1384 config_host_data.set('CONFIG_VTE', vte.found())
1385 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1386 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1387 config_host_data.set('CONFIG_EBPF', libbpf.found())
1388 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1389 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1390 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1391 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1392 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1393 config_host_data.set('CONFIG_RBD', rbd.found())
1394 config_host_data.set('CONFIG_SDL', sdl.found())
1395 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1396 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1397 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1398 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1399 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1400 config_host_data.set('CONFIG_VNC', vnc.found())
1401 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1402 config_host_data.set('CONFIG_VNC_PNG', png.found())
1403 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1404 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1405 config_host_data.set('CONFIG_VTE', vte.found())
1406 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1407 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1408 config_host_data.set('CONFIG_GETTID', has_gettid)
1409 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1410 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1411 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1412 config_host_data.set('CONFIG_NETTLE', nettle.found())
1413 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1414 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1415 config_host_data.set('CONFIG_STATX', has_statx)
1416 config_host_data.set('CONFIG_ZSTD', zstd.found())
1417 config_host_data.set('CONFIG_FUSE', fuse.found())
1418 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1419 config_host_data.set('CONFIG_X11', x11.found())
1420 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1421 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1422 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1423 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1424 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1426 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1429 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1430 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1431 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1432 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1433 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1434 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1435 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1436 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1437 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1440 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1441 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1442 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1443 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1444 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1445 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1446 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1447 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1448 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1449 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1450 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1451 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1452 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1453 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1454 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1455 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1456 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1457 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1460 config_host_data.set('CONFIG_BYTESWAP_H',
1461 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1462 config_host_data.set('CONFIG_EPOLL_CREATE1',
1463 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1464 config_host_data.set('CONFIG_HAS_ENVIRON',
1465 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1466 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1467 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1468 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1469 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1470 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1471 config_host_data.set('CONFIG_FIEMAP',
1472 cc.has_header('linux/fiemap.h') and
1473 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1474 config_host_data.set('CONFIG_GETRANDOM',
1475 cc.has_function('getrandom') and
1476 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1477 config_host_data.set('CONFIG_INOTIFY',
1478 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1479 config_host_data.set('CONFIG_INOTIFY1',
1480 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1481 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1482 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1483 prefix: '''#include <sys/endian.h>
1484 #include <sys/types.h>'''))
1485 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1486 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1487 config_host_data.set('CONFIG_RTNETLINK',
1488 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1489 config_host_data.set('CONFIG_SYSMACROS',
1490 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1491 config_host_data.set('HAVE_OPTRESET',
1492 cc.has_header_symbol('getopt.h', 'optreset'))
1493 config_host_data.set('HAVE_UTMPX',
1494 cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1495 config_host_data.set('HAVE_IPPROTO_MPTCP',
1496 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1499 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1500 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1501 prefix: '#include <signal.h>'))
1502 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1503 cc.has_member('struct stat', 'st_atim',
1504 prefix: '#include <sys/stat.h>'))
1506 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1507 #include <sys/eventfd.h>
1508 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1509 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1512 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1513 return fdatasync(0);
1515 #error Not supported
1518 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1519 #include <sys/types.h>
1520 #include <sys/mman.h>
1522 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1523 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1524 #include <sys/mman.h>
1525 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1526 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1528 #if !defined(AT_EMPTY_PATH)
1529 # error missing definition
1531 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1533 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1540 return pipe2(pipefd, O_CLOEXEC);
1542 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1543 #include <sys/mman.h>
1545 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1546 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1547 #include <sys/signalfd.h>
1549 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1550 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1558 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1559 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1563 # Some versions of Mac OS X incorrectly define SIZE_MAX
1564 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1567 int main(int argc, char *argv[]) {
1568 return printf("%zu", SIZE_MAX);
1569 }''', args: ['-Werror']))
1572 ignored = ['CONFIG_QEMU_INTERP_PREFIX'] # actually per-target
1573 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1574 strings = ['HOST_DSOSUF', 'CONFIG_IASL', 'CONFIG_TRACE_FILE']
1575 foreach k, v: config_host
1576 if ignored.contains(k)
1578 elif arrays.contains(k)
1580 v = '"' + '", "'.join(v.split()) + '", '
1582 config_host_data.set(k, v)
1584 config_host_data.set('HOST_' + v.to_upper(), 1)
1585 elif strings.contains(k)
1586 if not k.startswith('CONFIG_')
1587 k = 'CONFIG_' + k.to_upper()
1589 config_host_data.set_quoted(k, v)
1590 elif k.startswith('CONFIG_') or k.startswith('HAVE_') or k.startswith('HOST_')
1591 config_host_data.set(k, v == 'y' ? 1 : v)
1595 ########################
1596 # Target configuration #
1597 ########################
1599 minikconf = find_program('scripts/minikconf.py')
1601 config_all_devices = {}
1602 config_all_disas = {}
1603 config_devices_mak_list = []
1604 config_devices_h = {}
1605 config_target_h = {}
1606 config_target_mak = {}
1609 'alpha' : ['CONFIG_ALPHA_DIS'],
1610 'arm' : ['CONFIG_ARM_DIS'],
1611 'avr' : ['CONFIG_AVR_DIS'],
1612 'cris' : ['CONFIG_CRIS_DIS'],
1613 'hexagon' : ['CONFIG_HEXAGON_DIS'],
1614 'hppa' : ['CONFIG_HPPA_DIS'],
1615 'i386' : ['CONFIG_I386_DIS'],
1616 'x86_64' : ['CONFIG_I386_DIS'],
1617 'x32' : ['CONFIG_I386_DIS'],
1618 'm68k' : ['CONFIG_M68K_DIS'],
1619 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1620 'mips' : ['CONFIG_MIPS_DIS'],
1621 'nios2' : ['CONFIG_NIOS2_DIS'],
1622 'or1k' : ['CONFIG_OPENRISC_DIS'],
1623 'ppc' : ['CONFIG_PPC_DIS'],
1624 'riscv' : ['CONFIG_RISCV_DIS'],
1625 'rx' : ['CONFIG_RX_DIS'],
1626 's390' : ['CONFIG_S390_DIS'],
1627 'sh4' : ['CONFIG_SH4_DIS'],
1628 'sparc' : ['CONFIG_SPARC_DIS'],
1629 'xtensa' : ['CONFIG_XTENSA_DIS'],
1631 if link_language == 'cpp'
1633 'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1634 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1635 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1639 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1641 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1642 ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1643 ('CONFIG_SPICE' in config_host ? ['CONFIG_SPICE=y'] : []) + \
1644 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1645 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1646 (x11.found() ? ['CONFIG_X11=y'] : []) + \
1647 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1648 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1649 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1650 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1651 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1652 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1653 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1655 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1657 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1658 actual_target_dirs = []
1660 foreach target : target_dirs
1661 config_target = { 'TARGET_NAME': target.split('-')[0] }
1662 if target.endswith('linux-user')
1663 if targetos != 'linux'
1667 error('Target @0@ is only available on a Linux host'.format(target))
1669 config_target += { 'CONFIG_LINUX_USER': 'y' }
1670 elif target.endswith('bsd-user')
1671 if 'CONFIG_BSD' not in config_host
1675 error('Target @0@ is only available on a BSD host'.format(target))
1677 config_target += { 'CONFIG_BSD_USER': 'y' }
1678 elif target.endswith('softmmu')
1679 config_target += { 'CONFIG_SOFTMMU': 'y' }
1681 if target.endswith('-user')
1683 'CONFIG_USER_ONLY': 'y',
1684 'CONFIG_QEMU_INTERP_PREFIX':
1685 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1690 foreach sym: accelerators
1691 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1692 config_target += { sym: 'y' }
1693 config_all += { sym: 'y' }
1694 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1695 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1696 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1697 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1699 if target in modular_tcg
1700 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1702 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1704 accel_kconfig += [ sym + '=y' ]
1707 if accel_kconfig.length() == 0
1711 error('No accelerator available for target @0@'.format(target))
1714 actual_target_dirs += target
1715 config_target += keyval.load('configs/targets' / target + '.mak')
1716 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1718 if 'TARGET_NEED_FDT' in config_target
1719 fdt_required += target
1723 if 'TARGET_BASE_ARCH' not in config_target
1724 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1726 if 'TARGET_ABI_DIR' not in config_target
1727 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1730 foreach k, v: disassemblers
1731 if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1733 config_target += { sym: 'y' }
1734 config_all_disas += { sym: 'y' }
1739 config_target_data = configuration_data()
1740 foreach k, v: config_target
1741 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1743 elif ignored.contains(k)
1745 elif k == 'TARGET_BASE_ARCH'
1746 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1747 # not used to select files from sourcesets.
1748 config_target_data.set('TARGET_' + v.to_upper(), 1)
1749 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1750 config_target_data.set_quoted(k, v)
1752 config_target_data.set(k, 1)
1754 config_target_data.set(k, v)
1757 config_target_data.set('QEMU_ARCH',
1758 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1759 config_target_h += {target: configure_file(output: target + '-config-target.h',
1760 configuration: config_target_data)}
1762 if target.endswith('-softmmu')
1763 config_input = meson.get_external_property(target, 'default')
1764 config_devices_mak = target + '-config-devices.mak'
1765 config_devices_mak = configure_file(
1766 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1767 output: config_devices_mak,
1768 depfile: config_devices_mak + '.d',
1770 command: [minikconf,
1771 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1772 config_devices_mak, '@DEPFILE@', '@INPUT@',
1773 host_kconfig, accel_kconfig,
1774 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1776 config_devices_data = configuration_data()
1777 config_devices = keyval.load(config_devices_mak)
1778 foreach k, v: config_devices
1779 config_devices_data.set(k, 1)
1781 config_devices_mak_list += config_devices_mak
1782 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1783 configuration: config_devices_data)}
1784 config_target += config_devices
1785 config_all_devices += config_devices
1787 config_target_mak += {target: config_target}
1789 target_dirs = actual_target_dirs
1791 # This configuration is used to build files that are shared by
1792 # multiple binaries, and then extracted out of the "common"
1793 # static_library target.
1795 # We do not use all_sources()/all_dependencies(), because it would
1796 # build literally all source files, including devices only used by
1797 # targets that are not built for this compilation. The CONFIG_ALL
1798 # pseudo symbol replaces it.
1800 config_all += config_all_devices
1801 config_all += config_host
1802 config_all += config_all_disas
1804 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1805 'CONFIG_SOFTMMU': have_system,
1806 'CONFIG_USER_ONLY': have_user,
1814 capstone = not_found
1815 capstone_opt = get_option('capstone')
1816 if capstone_opt in ['enabled', 'auto', 'system']
1817 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
1818 capstone = dependency('capstone', version: '>=4.0',
1819 kwargs: static_kwargs, method: 'pkg-config',
1820 required: capstone_opt == 'system' or
1821 capstone_opt == 'enabled' and not have_internal)
1823 # Some versions of capstone have broken pkg-config file
1824 # that reports a wrong -I path, causing the #include to
1825 # fail later. If the system has such a broken version
1827 if capstone.found() and not cc.compiles('#include <capstone.h>',
1828 dependencies: [capstone])
1829 capstone = not_found
1830 if capstone_opt == 'system'
1831 error('system capstone requested, it does not appear to work')
1836 capstone_opt = 'system'
1838 capstone_opt = 'internal'
1840 capstone_opt = 'disabled'
1843 if capstone_opt == 'internal'
1844 capstone_data = configuration_data()
1845 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
1847 capstone_files = files(
1849 'capstone/MCInst.c',
1850 'capstone/MCInstrDesc.c',
1851 'capstone/MCRegisterInfo.c',
1852 'capstone/SStream.c',
1856 if 'CONFIG_ARM_DIS' in config_all_disas
1857 capstone_data.set('CAPSTONE_HAS_ARM', '1')
1858 capstone_files += files(
1859 'capstone/arch/ARM/ARMDisassembler.c',
1860 'capstone/arch/ARM/ARMInstPrinter.c',
1861 'capstone/arch/ARM/ARMMapping.c',
1862 'capstone/arch/ARM/ARMModule.c'
1866 # FIXME: This config entry currently depends on a c++ compiler.
1867 # Which is needed for building libvixl, but not for capstone.
1868 if 'CONFIG_ARM_A64_DIS' in config_all_disas
1869 capstone_data.set('CAPSTONE_HAS_ARM64', '1')
1870 capstone_files += files(
1871 'capstone/arch/AArch64/AArch64BaseInfo.c',
1872 'capstone/arch/AArch64/AArch64Disassembler.c',
1873 'capstone/arch/AArch64/AArch64InstPrinter.c',
1874 'capstone/arch/AArch64/AArch64Mapping.c',
1875 'capstone/arch/AArch64/AArch64Module.c'
1879 if 'CONFIG_PPC_DIS' in config_all_disas
1880 capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
1881 capstone_files += files(
1882 'capstone/arch/PowerPC/PPCDisassembler.c',
1883 'capstone/arch/PowerPC/PPCInstPrinter.c',
1884 'capstone/arch/PowerPC/PPCMapping.c',
1885 'capstone/arch/PowerPC/PPCModule.c'
1889 if 'CONFIG_S390_DIS' in config_all_disas
1890 capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
1891 capstone_files += files(
1892 'capstone/arch/SystemZ/SystemZDisassembler.c',
1893 'capstone/arch/SystemZ/SystemZInstPrinter.c',
1894 'capstone/arch/SystemZ/SystemZMapping.c',
1895 'capstone/arch/SystemZ/SystemZModule.c',
1896 'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
1900 if 'CONFIG_I386_DIS' in config_all_disas
1901 capstone_data.set('CAPSTONE_HAS_X86', 1)
1902 capstone_files += files(
1903 'capstone/arch/X86/X86Disassembler.c',
1904 'capstone/arch/X86/X86DisassemblerDecoder.c',
1905 'capstone/arch/X86/X86ATTInstPrinter.c',
1906 'capstone/arch/X86/X86IntelInstPrinter.c',
1907 'capstone/arch/X86/X86InstPrinterCommon.c',
1908 'capstone/arch/X86/X86Mapping.c',
1909 'capstone/arch/X86/X86Module.c'
1913 configure_file(output: 'capstone-defs.h', configuration: capstone_data)
1916 # FIXME: There does not seem to be a way to completely replace the c_args
1917 # that come from add_project_arguments() -- we can only add to them.
1918 # So: disable all warnings with a big hammer.
1921 # Include all configuration defines via a header file, which will wind up
1922 # as a dependency on the object file, and thus changes here will result
1924 '-include', 'capstone-defs.h'
1927 libcapstone = static_library('capstone',
1928 build_by_default: false,
1929 sources: capstone_files,
1930 c_args: capstone_cargs,
1931 include_directories: 'capstone/include')
1932 capstone = declare_dependency(link_with: libcapstone,
1933 include_directories: 'capstone/include/capstone')
1937 slirp_opt = 'disabled'
1939 slirp_opt = get_option('slirp')
1940 if slirp_opt in ['enabled', 'auto', 'system']
1941 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
1942 slirp = dependency('slirp', kwargs: static_kwargs,
1943 method: 'pkg-config',
1944 required: slirp_opt == 'system' or
1945 slirp_opt == 'enabled' and not have_internal)
1947 slirp_opt = 'system'
1949 slirp_opt = 'internal'
1951 slirp_opt = 'disabled'
1954 if slirp_opt == 'internal'
1956 if targetos == 'windows'
1957 slirp_deps = cc.find_library('iphlpapi')
1958 elif targetos == 'darwin'
1959 slirp_deps = cc.find_library('resolv')
1961 slirp_conf = configuration_data()
1962 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
1963 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
1964 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
1965 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
1966 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
1968 'slirp/src/arp_table.c',
1969 'slirp/src/bootp.c',
1970 'slirp/src/cksum.c',
1971 'slirp/src/dhcpv6.c',
1972 'slirp/src/dnssearch.c',
1974 'slirp/src/ip6_icmp.c',
1975 'slirp/src/ip6_input.c',
1976 'slirp/src/ip6_output.c',
1977 'slirp/src/ip_icmp.c',
1978 'slirp/src/ip_input.c',
1979 'slirp/src/ip_output.c',
1983 'slirp/src/ndp_table.c',
1985 'slirp/src/slirp.c',
1986 'slirp/src/socket.c',
1987 'slirp/src/state.c',
1988 'slirp/src/stream.c',
1989 'slirp/src/tcp_input.c',
1990 'slirp/src/tcp_output.c',
1991 'slirp/src/tcp_subr.c',
1992 'slirp/src/tcp_timer.c',
1997 'slirp/src/version.c',
1998 'slirp/src/vmstate.c',
2002 input : 'slirp/src/libslirp-version.h.in',
2003 output : 'libslirp-version.h',
2004 configuration: slirp_conf)
2006 slirp_inc = include_directories('slirp', 'slirp/src')
2007 libslirp = static_library('slirp',
2008 build_by_default: false,
2009 sources: slirp_files,
2010 c_args: slirp_cargs,
2011 include_directories: slirp_inc)
2012 slirp = declare_dependency(link_with: libslirp,
2013 dependencies: slirp_deps,
2014 include_directories: slirp_inc)
2018 # For CFI, we need to compile slirp as a static library together with qemu.
2019 # This is because we register slirp functions as callbacks for QEMU Timers.
2020 # When using a system-wide shared libslirp, the type information for the
2021 # callback is missing and the timer call produces a false positive with CFI.
2023 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2024 # with control-flow integrity.
2025 if get_option('cfi') and slirp_opt == 'system'
2026 error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2027 + ' Please configure with --enable-slirp=git')
2031 fdt_opt = get_option('fdt')
2033 if fdt_opt in ['enabled', 'auto', 'system']
2034 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2035 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2036 required: fdt_opt == 'system' or
2037 fdt_opt == 'enabled' and not have_internal)
2038 if fdt.found() and cc.links('''
2040 #include <libfdt_env.h>
2041 int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2044 elif fdt_opt == 'system'
2045 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2047 fdt_opt = 'internal'
2049 fdt_opt = 'disabled'
2053 if fdt_opt == 'internal'
2056 'dtc/libfdt/fdt_ro.c',
2057 'dtc/libfdt/fdt_wip.c',
2058 'dtc/libfdt/fdt_sw.c',
2059 'dtc/libfdt/fdt_rw.c',
2060 'dtc/libfdt/fdt_strerror.c',
2061 'dtc/libfdt/fdt_empty_tree.c',
2062 'dtc/libfdt/fdt_addresses.c',
2063 'dtc/libfdt/fdt_overlay.c',
2064 'dtc/libfdt/fdt_check.c',
2067 fdt_inc = include_directories('dtc/libfdt')
2068 libfdt = static_library('fdt',
2069 build_by_default: false,
2071 include_directories: fdt_inc)
2072 fdt = declare_dependency(link_with: libfdt,
2073 include_directories: fdt_inc)
2076 if not fdt.found() and fdt_required.length() > 0
2077 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2080 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2081 config_host_data.set('CONFIG_FDT', fdt.found())
2082 config_host_data.set('CONFIG_SLIRP', slirp.found())
2084 #####################
2085 # Generated sources #
2086 #####################
2088 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2090 hxtool = find_program('scripts/hxtool')
2091 shaderinclude = find_program('scripts/shaderinclude.pl')
2092 qapi_gen = find_program('scripts/qapi-gen.py')
2093 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2094 meson.current_source_dir() / 'scripts/qapi/commands.py',
2095 meson.current_source_dir() / 'scripts/qapi/common.py',
2096 meson.current_source_dir() / 'scripts/qapi/error.py',
2097 meson.current_source_dir() / 'scripts/qapi/events.py',
2098 meson.current_source_dir() / 'scripts/qapi/expr.py',
2099 meson.current_source_dir() / 'scripts/qapi/gen.py',
2100 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2101 meson.current_source_dir() / 'scripts/qapi/parser.py',
2102 meson.current_source_dir() / 'scripts/qapi/schema.py',
2103 meson.current_source_dir() / 'scripts/qapi/source.py',
2104 meson.current_source_dir() / 'scripts/qapi/types.py',
2105 meson.current_source_dir() / 'scripts/qapi/visit.py',
2106 meson.current_source_dir() / 'scripts/qapi/common.py',
2107 meson.current_source_dir() / 'scripts/qapi-gen.py'
2111 python, files('scripts/tracetool.py'),
2112 '--backend=' + config_host['TRACE_BACKENDS']
2114 tracetool_depends = files(
2115 'scripts/tracetool/backend/log.py',
2116 'scripts/tracetool/backend/__init__.py',
2117 'scripts/tracetool/backend/dtrace.py',
2118 'scripts/tracetool/backend/ftrace.py',
2119 'scripts/tracetool/backend/simple.py',
2120 'scripts/tracetool/backend/syslog.py',
2121 'scripts/tracetool/backend/ust.py',
2122 'scripts/tracetool/format/tcg_h.py',
2123 'scripts/tracetool/format/ust_events_c.py',
2124 'scripts/tracetool/format/ust_events_h.py',
2125 'scripts/tracetool/format/__init__.py',
2126 'scripts/tracetool/format/d.py',
2127 'scripts/tracetool/format/tcg_helper_c.py',
2128 'scripts/tracetool/format/simpletrace_stap.py',
2129 'scripts/tracetool/format/c.py',
2130 'scripts/tracetool/format/h.py',
2131 'scripts/tracetool/format/tcg_helper_h.py',
2132 'scripts/tracetool/format/log_stap.py',
2133 'scripts/tracetool/format/stap.py',
2134 'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2135 'scripts/tracetool/__init__.py',
2136 'scripts/tracetool/transform.py',
2137 'scripts/tracetool/vcpu.py'
2140 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2141 meson.current_source_dir(),
2142 config_host['PKGVERSION'], meson.project_version()]
2143 qemu_version = custom_target('qemu-version.h',
2144 output: 'qemu-version.h',
2145 command: qemu_version_cmd,
2147 build_by_default: true,
2148 build_always_stale: true)
2149 genh += qemu_version
2153 ['qemu-options.hx', 'qemu-options.def'],
2154 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2158 ['hmp-commands.hx', 'hmp-commands.h'],
2159 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2162 foreach d : hx_headers
2163 hxdep += custom_target(d[1],
2167 build_by_default: true, # to be removed when added to a target
2168 command: [hxtool, '-h', '@INPUT0@'])
2176 authz_ss = ss.source_set()
2177 blockdev_ss = ss.source_set()
2178 block_ss = ss.source_set()
2179 bsd_user_ss = ss.source_set()
2180 chardev_ss = ss.source_set()
2181 common_ss = ss.source_set()
2182 crypto_ss = ss.source_set()
2183 io_ss = ss.source_set()
2184 linux_user_ss = ss.source_set()
2185 qmp_ss = ss.source_set()
2186 qom_ss = ss.source_set()
2187 softmmu_ss = ss.source_set()
2188 specific_fuzz_ss = ss.source_set()
2189 specific_ss = ss.source_set()
2190 stub_ss = ss.source_set()
2191 trace_ss = ss.source_set()
2192 user_ss = ss.source_set()
2193 util_ss = ss.source_set()
2196 qtest_module_ss = ss.source_set()
2197 tcg_module_ss = ss.source_set()
2203 target_softmmu_arch = {}
2204 target_user_arch = {}
2210 # TODO: add each directory to the subdirs from its own meson.build, once
2212 trace_events_subdirs = [
2220 trace_events_subdirs += [ 'linux-user' ]
2223 trace_events_subdirs += [
2232 trace_events_subdirs += [
2246 'hw/block/dataplane',
2295 if have_system or have_user
2296 trace_events_subdirs += [
2313 vhost_user = not_found
2314 if 'CONFIG_VHOST_USER' in config_host
2315 libvhost_user = subproject('libvhost-user')
2316 vhost_user = libvhost_user.get_variable('vhost_user_dep')
2331 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2332 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2335 stub_ss = stub_ss.apply(config_all, strict: false)
2337 util_ss.add_all(trace_ss)
2338 util_ss = util_ss.apply(config_all, strict: false)
2339 libqemuutil = static_library('qemuutil',
2340 sources: util_ss.sources() + stub_ss.sources() + genh,
2341 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2342 qemuutil = declare_dependency(link_with: libqemuutil,
2343 sources: genh + version_res)
2345 if have_system or have_user
2346 decodetree = generator(find_program('scripts/decodetree.py'),
2347 output: 'decode-@BASENAME@.c.inc',
2348 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2349 subdir('libdecnumber')
2366 block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2372 blockdev_ss.add(files(
2379 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2380 # os-win32.c does not
2381 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2382 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2385 common_ss.add(files('cpus-common.c'))
2389 common_ss.add(capstone)
2390 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2392 # Work around a gcc bug/misfeature wherein constant propagation looks
2394 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2395 # to guess that a const variable is always zero. Without lto, this is
2396 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
2397 # without lto, not even the alias is required -- we simply use different
2398 # declarations in different compilation units.
2399 pagevary = files('page-vary-common.c')
2400 if get_option('b_lto')
2401 pagevary_flags = ['-fno-lto']
2402 if get_option('cfi')
2403 pagevary_flags += '-fno-sanitize=cfi-icall'
2405 pagevary = static_library('page-vary-common', sources: pagevary,
2406 c_args: pagevary_flags)
2407 pagevary = declare_dependency(link_with: pagevary)
2409 common_ss.add(pagevary)
2410 specific_ss.add(files('page-vary.c'))
2418 subdir('semihosting')
2425 subdir('linux-user')
2428 bsd_user_ss.add(files('gdbstub.c'))
2429 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2431 linux_user_ss.add(files('gdbstub.c', 'thunk.c'))
2432 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2434 # needed for fuzzing binaries
2435 subdir('tests/qtest/libqos')
2436 subdir('tests/qtest/fuzz')
2439 tcg_real_module_ss = ss.source_set()
2440 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2441 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2442 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2443 'tcg': tcg_real_module_ss }}
2445 ########################
2446 # Library dependencies #
2447 ########################
2449 modinfo_collect = find_program('scripts/modinfo-collect.py')
2450 modinfo_generate = find_program('scripts/modinfo-generate.py')
2455 foreach d, list : modules
2456 foreach m, module_ss : list
2457 if enable_modules and targetos != 'windows'
2458 module_ss = module_ss.apply(config_all, strict: false)
2459 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2460 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2466 if module_ss.sources() != []
2467 # FIXME: Should use sl.extract_all_objects(recursive: true) as
2468 # input. Sources can be used multiple times but objects are
2469 # unique when it comes to lookup in compile_commands.json.
2470 # Depnds on a mesion version with
2471 # https://github.com/mesonbuild/meson/pull/8900
2472 modinfo_files += custom_target(d + '-' + m + '.modinfo',
2473 output: d + '-' + m + '.modinfo',
2474 input: module_ss.sources() + genh,
2476 command: [modinfo_collect, module_ss.sources()])
2480 block_ss.add_all(module_ss)
2482 softmmu_ss.add_all(module_ss)
2488 foreach d, list : target_modules
2489 foreach m, module_ss : list
2490 if enable_modules and targetos != 'windows'
2491 foreach target : target_dirs
2492 if target.endswith('-softmmu')
2493 config_target = config_target_mak[target]
2494 config_target += config_host
2495 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2496 c_args = ['-DNEED_CPU_H',
2497 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2498 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2499 target_module_ss = module_ss.apply(config_target, strict: false)
2500 if target_module_ss.sources() != []
2501 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2502 sl = static_library(module_name,
2503 [genh, target_module_ss.sources()],
2504 dependencies: [modulecommon, target_module_ss.dependencies()],
2505 include_directories: target_inc,
2509 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2510 modinfo_files += custom_target(module_name + '.modinfo',
2511 output: module_name + '.modinfo',
2512 input: target_module_ss.sources() + genh,
2514 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2519 specific_ss.add_all(module_ss)
2525 modinfo_src = custom_target('modinfo.c',
2526 output: 'modinfo.c',
2527 input: modinfo_files,
2528 command: [modinfo_generate, '@INPUT@'],
2530 modinfo_lib = static_library('modinfo', modinfo_src)
2531 modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2532 softmmu_ss.add(modinfo_dep)
2535 nm = find_program('nm')
2536 undefsym = find_program('scripts/undefsym.py')
2537 block_syms = custom_target('block.syms', output: 'block.syms',
2538 input: [libqemuutil, block_mods],
2540 command: [undefsym, nm, '@INPUT@'])
2541 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2542 input: [libqemuutil, softmmu_mods],
2544 command: [undefsym, nm, '@INPUT@'])
2546 qom_ss = qom_ss.apply(config_host, strict: false)
2547 libqom = static_library('qom', qom_ss.sources() + genh,
2548 dependencies: [qom_ss.dependencies()],
2551 qom = declare_dependency(link_whole: libqom)
2553 authz_ss = authz_ss.apply(config_host, strict: false)
2554 libauthz = static_library('authz', authz_ss.sources() + genh,
2555 dependencies: [authz_ss.dependencies()],
2557 build_by_default: false)
2559 authz = declare_dependency(link_whole: libauthz,
2562 crypto_ss = crypto_ss.apply(config_host, strict: false)
2563 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2564 dependencies: [crypto_ss.dependencies()],
2566 build_by_default: false)
2568 crypto = declare_dependency(link_whole: libcrypto,
2569 dependencies: [authz, qom])
2571 io_ss = io_ss.apply(config_host, strict: false)
2572 libio = static_library('io', io_ss.sources() + genh,
2573 dependencies: [io_ss.dependencies()],
2574 link_with: libqemuutil,
2576 build_by_default: false)
2578 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2580 libmigration = static_library('migration', sources: migration_files + genh,
2582 build_by_default: false)
2583 migration = declare_dependency(link_with: libmigration,
2584 dependencies: [zlib, qom, io])
2585 softmmu_ss.add(migration)
2587 block_ss = block_ss.apply(config_host, strict: false)
2588 libblock = static_library('block', block_ss.sources() + genh,
2589 dependencies: block_ss.dependencies(),
2590 link_depends: block_syms,
2592 build_by_default: false)
2594 block = declare_dependency(link_whole: [libblock],
2595 link_args: '@block.syms',
2596 dependencies: [crypto, io])
2598 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2599 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2600 dependencies: blockdev_ss.dependencies(),
2602 build_by_default: false)
2604 blockdev = declare_dependency(link_whole: [libblockdev],
2605 dependencies: [block])
2607 qmp_ss = qmp_ss.apply(config_host, strict: false)
2608 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2609 dependencies: qmp_ss.dependencies(),
2611 build_by_default: false)
2613 qmp = declare_dependency(link_whole: [libqmp])
2615 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2617 dependencies: [gnutls],
2618 build_by_default: false)
2620 chardev = declare_dependency(link_whole: libchardev)
2622 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2624 build_by_default: false)
2625 hwcore = declare_dependency(link_whole: libhwcore)
2626 common_ss.add(hwcore)
2632 foreach m : block_mods + softmmu_mods
2633 shared_module(m.name(),
2637 install_dir: qemu_moddir)
2640 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2641 common_ss.add(qom, qemuutil)
2643 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2644 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2646 common_all = common_ss.apply(config_all, strict: false)
2647 common_all = static_library('common',
2648 build_by_default: false,
2649 sources: common_all.sources() + genh,
2650 implicit_include_directories: false,
2651 dependencies: common_all.dependencies(),
2654 feature_to_c = find_program('scripts/feature_to_c.sh')
2657 foreach target : target_dirs
2658 config_target = config_target_mak[target]
2659 target_name = config_target['TARGET_NAME']
2660 arch = config_target['TARGET_BASE_ARCH']
2661 arch_srcs = [config_target_h[target]]
2663 c_args = ['-DNEED_CPU_H',
2664 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2665 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2666 link_args = emulator_link_args
2668 config_target += config_host
2669 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2670 if targetos == 'linux'
2671 target_inc += include_directories('linux-headers', is_system: true)
2673 if target.endswith('-softmmu')
2674 qemu_target_name = 'qemu-system-' + target_name
2675 target_type='system'
2676 t = target_softmmu_arch[arch].apply(config_target, strict: false)
2677 arch_srcs += t.sources()
2678 arch_deps += t.dependencies()
2680 hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2681 hw = hw_arch[hw_dir].apply(config_target, strict: false)
2682 arch_srcs += hw.sources()
2683 arch_deps += hw.dependencies()
2685 arch_srcs += config_devices_h[target]
2686 link_args += ['@block.syms', '@qemu.syms']
2688 abi = config_target['TARGET_ABI_DIR']
2690 qemu_target_name = 'qemu-' + target_name
2691 if arch in target_user_arch
2692 t = target_user_arch[arch].apply(config_target, strict: false)
2693 arch_srcs += t.sources()
2694 arch_deps += t.dependencies()
2696 if 'CONFIG_LINUX_USER' in config_target
2697 base_dir = 'linux-user'
2698 target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2700 if 'CONFIG_BSD_USER' in config_target
2701 base_dir = 'bsd-user'
2702 target_inc += include_directories('bsd-user/' / targetos)
2703 dir = base_dir / abi
2704 arch_srcs += files(dir / 'target_arch_cpu.c')
2706 target_inc += include_directories(
2710 if 'CONFIG_LINUX_USER' in config_target
2711 dir = base_dir / abi
2712 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2713 if config_target.has_key('TARGET_SYSTBL_ABI')
2715 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2716 extra_args : config_target['TARGET_SYSTBL_ABI'])
2721 if 'TARGET_XML_FILES' in config_target
2722 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2723 output: target + '-gdbstub-xml.c',
2724 input: files(config_target['TARGET_XML_FILES'].split()),
2725 command: [feature_to_c, '@INPUT@'],
2727 arch_srcs += gdbstub_xml
2730 t = target_arch[arch].apply(config_target, strict: false)
2731 arch_srcs += t.sources()
2732 arch_deps += t.dependencies()
2734 target_common = common_ss.apply(config_target, strict: false)
2735 objects = common_all.extract_objects(target_common.sources())
2736 deps = target_common.dependencies()
2738 target_specific = specific_ss.apply(config_target, strict: false)
2739 arch_srcs += target_specific.sources()
2740 arch_deps += target_specific.dependencies()
2742 lib = static_library('qemu-' + target,
2743 sources: arch_srcs + genh,
2744 dependencies: arch_deps,
2746 include_directories: target_inc,
2748 build_by_default: false,
2751 if target.endswith('-softmmu')
2753 'name': 'qemu-system-' + target_name,
2754 'win_subsystem': 'console',
2755 'sources': files('softmmu/main.c'),
2758 if targetos == 'windows' and (sdl.found() or gtk.found())
2760 'name': 'qemu-system-' + target_name + 'w',
2761 'win_subsystem': 'windows',
2762 'sources': files('softmmu/main.c'),
2766 if get_option('fuzzing')
2767 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2769 'name': 'qemu-fuzz-' + target_name,
2770 'win_subsystem': 'console',
2771 'sources': specific_fuzz.sources(),
2772 'dependencies': specific_fuzz.dependencies(),
2777 'name': 'qemu-' + target_name,
2778 'win_subsystem': 'console',
2784 exe_name = exe['name']
2785 if targetos == 'darwin'
2786 exe_name += '-unsigned'
2789 emulator = executable(exe_name, exe['sources'],
2792 dependencies: arch_deps + deps + exe['dependencies'],
2793 objects: lib.extract_all_objects(recursive: true),
2794 link_language: link_language,
2795 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2796 link_args: link_args,
2797 win_subsystem: exe['win_subsystem'])
2799 if targetos == 'darwin'
2800 icon = 'pc-bios/qemu.rsrc'
2801 build_input = [emulator, files(icon)]
2803 get_option('bindir') / exe_name,
2804 meson.current_source_dir() / icon
2806 if 'CONFIG_HVF' in config_target
2807 entitlements = 'accel/hvf/entitlements.plist'
2808 build_input += files(entitlements)
2809 install_input += meson.current_source_dir() / entitlements
2812 emulators += {exe['name'] : custom_target(exe['name'],
2814 output: exe['name'],
2816 files('scripts/entitlement.sh'),
2822 meson.add_install_script('scripts/entitlement.sh', '--install',
2823 get_option('bindir') / exe['name'],
2826 emulators += {exe['name']: emulator}
2829 if 'CONFIG_TRACE_SYSTEMTAP' in config_host
2831 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
2832 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
2833 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
2834 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
2836 custom_target(exe['name'] + stp['ext'],
2837 input: trace_events_all,
2838 output: exe['name'] + stp['ext'],
2839 install: stp['install'],
2840 install_dir: get_option('datadir') / 'systemtap/tapset',
2842 tracetool, '--group=all', '--format=' + stp['fmt'],
2843 '--binary=' + stp['bin'],
2844 '--target-name=' + target_name,
2845 '--target-type=' + target_type,
2846 '--probe-prefix=qemu.' + target_type + '.' + target_name,
2847 '@INPUT@', '@OUTPUT@'
2849 depend_files: tracetool_depends)
2855 # Other build targets
2857 if 'CONFIG_PLUGIN' in config_host
2858 install_headers('include/qemu/qemu-plugin.h')
2861 if 'CONFIG_GUEST_AGENT' in config_host
2863 elif get_option('guest_agent_msi').enabled()
2864 error('Guest agent MSI requested, but the guest agent is not being built')
2867 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
2868 # when we don't build tools or system
2869 if xkbcommon.found()
2870 # used for the update-keymaps target, so include rules even if !have_tools
2871 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
2872 dependencies: [qemuutil, xkbcommon], install: have_tools)
2876 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
2877 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
2878 qemu_io = executable('qemu-io', files('qemu-io.c'),
2879 dependencies: [block, qemuutil], install: true)
2880 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
2881 dependencies: [blockdev, qemuutil, gnutls], install: true)
2883 subdir('storage-daemon')
2884 subdir('contrib/rdmacm-mux')
2885 subdir('contrib/elf2dmp')
2887 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
2888 dependencies: qemuutil,
2891 if 'CONFIG_VHOST_USER' in config_host
2892 subdir('contrib/vhost-user-blk')
2893 subdir('contrib/vhost-user-gpu')
2894 subdir('contrib/vhost-user-input')
2895 subdir('contrib/vhost-user-scsi')
2898 if targetos == 'linux'
2899 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
2900 dependencies: [qemuutil, libcap_ng],
2902 install_dir: get_option('libexecdir'))
2904 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
2905 dependencies: [authz, crypto, io, qom, qemuutil,
2906 libcap_ng, mpathpersist],
2911 subdir('contrib/ivshmem-client')
2912 subdir('contrib/ivshmem-server')
2925 if host_machine.system() == 'windows'
2927 find_program('scripts/nsis.py'),
2929 get_option('prefix'),
2930 meson.current_source_dir(),
2933 '-DDISPLAYVERSION=' + meson.project_version(),
2936 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
2939 nsis_cmd += '-DCONFIG_GTK=y'
2942 nsis = custom_target('nsis',
2943 output: 'qemu-setup-' + meson.project_version() + '.exe',
2944 input: files('qemu.nsi'),
2945 build_always_stale: true,
2946 command: nsis_cmd + ['@INPUT@'])
2947 alias_target('installer', nsis)
2950 #########################
2951 # Configuration summary #
2952 #########################
2956 summary_info += {'Install prefix': get_option('prefix')}
2957 summary_info += {'BIOS directory': qemu_datadir}
2958 summary_info += {'firmware path': get_option('qemu_firmwarepath')}
2959 summary_info += {'binary directory': get_option('bindir')}
2960 summary_info += {'library directory': get_option('libdir')}
2961 summary_info += {'module directory': qemu_moddir}
2962 summary_info += {'libexec directory': get_option('libexecdir')}
2963 summary_info += {'include directory': get_option('includedir')}
2964 summary_info += {'config directory': get_option('sysconfdir')}
2965 if targetos != 'windows'
2966 summary_info += {'local state directory': get_option('localstatedir')}
2967 summary_info += {'Manual directory': get_option('mandir')}
2969 summary_info += {'local state directory': 'queried at runtime'}
2971 summary_info += {'Doc directory': get_option('docdir')}
2972 summary_info += {'Build directory': meson.current_build_dir()}
2973 summary_info += {'Source path': meson.current_source_dir()}
2974 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
2975 summary(summary_info, bool_yn: true, section: 'Directories')
2979 summary_info += {'git': config_host['GIT']}
2980 summary_info += {'make': config_host['MAKE']}
2981 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
2982 summary_info += {'sphinx-build': sphinx_build}
2983 if config_host.has_key('HAVE_GDB_BIN')
2984 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
2986 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
2987 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
2988 summary_info += {'wixl': wixl}
2990 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
2991 summary_info += {'smbd': config_host['CONFIG_SMBD_COMMAND']}
2993 summary(summary_info, bool_yn: true, section: 'Host binaries')
2995 # Configurable features
2997 summary_info += {'Documentation': build_docs}
2998 summary_info += {'system-mode emulation': have_system}
2999 summary_info += {'user-mode emulation': have_user}
3000 summary_info += {'block layer': have_block}
3001 summary_info += {'Install blobs': get_option('install_blobs')}
3002 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3003 if config_host.has_key('CONFIG_MODULES')
3004 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3006 summary_info += {'fuzzing support': get_option('fuzzing')}
3008 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3010 summary_info += {'Trace backends': config_host['TRACE_BACKENDS']}
3011 if config_host['TRACE_BACKENDS'].split().contains('simple')
3012 summary_info += {'Trace output file': config_host['CONFIG_TRACE_FILE'] + '-<pid>'}
3014 summary_info += {'QOM debugging': config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3015 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3016 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3017 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3018 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3019 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3020 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3021 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3022 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3023 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3024 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3025 summary(summary_info, bool_yn: true, section: 'Configurable features')
3027 # Compilation information
3029 summary_info += {'host CPU': cpu}
3030 summary_info += {'host endianness': build_machine.endian()}
3031 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3032 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3033 if link_language == 'cpp'
3034 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3036 summary_info += {'C++ compiler': false}
3038 if targetos == 'darwin'
3039 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3041 if targetos == 'windows'
3042 if 'WIN_SDK' in config_host
3043 summary_info += {'Windows SDK': config_host['WIN_SDK']}
3046 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3047 + ['-O' + get_option('optimization')]
3048 + (get_option('debug') ? ['-g'] : []))}
3049 if link_language == 'cpp'
3050 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3051 + ['-O' + get_option('optimization')]
3052 + (get_option('debug') ? ['-g'] : []))}
3054 link_args = get_option(link_language + '_link_args')
3055 if link_args.length() > 0
3056 summary_info += {'LDFLAGS': ' '.join(link_args)}
3058 summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
3059 summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
3060 summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
3061 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3062 summary_info += {'PIE': get_option('b_pie')}
3063 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3064 summary_info += {'malloc trim support': has_malloc_trim}
3065 summary_info += {'membarrier': config_host.has_key('CONFIG_MEMBARRIER')}
3066 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3067 summary_info += {'mutex debugging': config_host.has_key('CONFIG_DEBUG_MUTEX')}
3068 summary_info += {'memory allocator': get_option('malloc')}
3069 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3070 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3071 summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
3072 summary_info += {'gcov': get_option('b_coverage')}
3073 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3074 summary_info += {'CFI support': get_option('cfi')}
3075 if get_option('cfi')
3076 summary_info += {'CFI debug support': get_option('cfi_debug')}
3078 summary_info += {'strip binaries': get_option('strip')}
3079 summary_info += {'sparse': sparse}
3080 summary_info += {'mingw32 support': targetos == 'windows'}
3082 # snarf the cross-compilation information for tests
3083 foreach target: target_dirs
3084 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3085 if fs.exists(tcg_mak)
3086 config_cross_tcg = keyval.load(tcg_mak)
3087 target = config_cross_tcg['TARGET_NAME']
3089 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3090 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3091 ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3092 elif 'CROSS_CC_GUEST' in config_cross_tcg
3093 summary_info += {target + ' tests'
3094 : config_cross_tcg['CROSS_CC_GUEST'] }
3099 summary(summary_info, bool_yn: true, section: 'Compilation')
3101 # Targets and accelerators
3104 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3105 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3106 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3107 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3108 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3109 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')}
3110 if config_host.has_key('CONFIG_XEN_BACKEND')
3111 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3114 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3115 if config_all.has_key('CONFIG_TCG')
3116 if get_option('tcg_interpreter')
3117 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, experimental and slow)'}
3119 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3121 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3122 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3124 summary_info += {'target list': ' '.join(target_dirs)}
3126 summary_info += {'default devices': get_option('default_devices')}
3127 summary_info += {'out of process emulation': multiprocess_allowed}
3129 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3133 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3134 summary_info += {'coroutine pool': config_host['CONFIG_COROUTINE_POOL'] == '1'}
3136 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3137 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3138 summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3139 summary_info += {'VirtFS support': have_virtfs}
3140 summary_info += {'build virtiofs daemon': have_virtiofsd}
3141 summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3142 summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3143 summary_info += {'bochs support': config_host.has_key('CONFIG_BOCHS')}
3144 summary_info += {'cloop support': config_host.has_key('CONFIG_CLOOP')}
3145 summary_info += {'dmg support': config_host.has_key('CONFIG_DMG')}
3146 summary_info += {'qcow v1 support': config_host.has_key('CONFIG_QCOW1')}
3147 summary_info += {'vdi support': config_host.has_key('CONFIG_VDI')}
3148 summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
3149 summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
3150 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3151 summary_info += {'FUSE exports': fuse}
3153 summary(summary_info, bool_yn: true, section: 'Block layer support')
3157 summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']}
3158 summary_info += {'GNUTLS support': gnutls}
3160 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3162 summary_info += {'libgcrypt': gcrypt}
3163 summary_info += {'nettle': nettle}
3165 summary_info += {' XTS': xts != 'private'}
3167 summary_info += {'crypto afalg': config_host.has_key('CONFIG_AF_ALG')}
3168 summary_info += {'rng-none': config_host.has_key('CONFIG_RNG_NONE')}
3169 summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')}
3170 summary(summary_info, bool_yn: true, section: 'Crypto')
3174 if targetos == 'darwin'
3175 summary_info += {'Cocoa support': cocoa}
3177 summary_info += {'SDL support': sdl}
3178 summary_info += {'SDL image support': sdl_image}
3179 summary_info += {'GTK support': gtk}
3180 summary_info += {'pixman': pixman}
3181 summary_info += {'VTE support': vte}
3182 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3183 summary_info += {'libtasn1': tasn1}
3184 summary_info += {'PAM': pam}
3185 summary_info += {'iconv support': iconv}
3186 summary_info += {'curses support': curses}
3187 summary_info += {'virgl support': virgl}
3188 summary_info += {'curl support': curl}
3189 summary_info += {'Multipath support': mpathpersist}
3190 summary_info += {'VNC support': vnc}
3192 summary_info += {'VNC SASL support': sasl}
3193 summary_info += {'VNC JPEG support': jpeg}
3194 summary_info += {'VNC PNG support': png}
3196 if targetos not in ['darwin', 'haiku', 'windows']
3197 summary_info += {'OSS support': oss}
3198 elif targetos == 'darwin'
3199 summary_info += {'CoreAudio support': coreaudio}
3200 elif targetos == 'windows'
3201 summary_info += {'DirectSound support': dsound}
3203 if targetos == 'linux'
3204 summary_info += {'ALSA support': alsa}
3205 summary_info += {'PulseAudio support': pulse}
3207 summary_info += {'JACK support': jack}
3208 summary_info += {'brlapi support': brlapi}
3209 summary_info += {'vde support': config_host.has_key('CONFIG_VDE')}
3210 summary_info += {'netmap support': config_host.has_key('CONFIG_NETMAP')}
3211 summary_info += {'Linux AIO support': config_host.has_key('CONFIG_LINUX_AIO')}
3212 summary_info += {'Linux io_uring support': linux_io_uring}
3213 summary_info += {'ATTR/XATTR support': libattr}
3214 summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')}
3215 summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')}
3216 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3217 summary_info += {'libcap-ng support': libcap_ng}
3218 summary_info += {'bpf support': libbpf}
3219 # TODO: add back protocol and server version
3220 summary_info += {'spice support': config_host.has_key('CONFIG_SPICE')}
3221 summary_info += {'rbd support': rbd}
3222 summary_info += {'xfsctl support': config_host.has_key('CONFIG_XFS')}
3223 summary_info += {'smartcard support': cacard}
3224 summary_info += {'U2F support': u2f}
3225 summary_info += {'libusb': libusb}
3226 summary_info += {'usb net redir': usbredir}
3227 summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')}
3228 summary_info += {'GBM': gbm}
3229 summary_info += {'libiscsi support': libiscsi}
3230 summary_info += {'libnfs support': libnfs}
3231 if targetos == 'windows'
3232 if config_host.has_key('CONFIG_GUEST_AGENT')
3233 summary_info += {'QGA VSS support': config_host.has_key('CONFIG_QGA_VSS')}
3234 summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3237 summary_info += {'seccomp support': seccomp}
3238 summary_info += {'GlusterFS support': glusterfs}
3239 summary_info += {'TPM support': config_host.has_key('CONFIG_TPM')}
3240 summary_info += {'libssh support': config_host.has_key('CONFIG_LIBSSH')}
3241 summary_info += {'lzo support': lzo}
3242 summary_info += {'snappy support': snappy}
3243 summary_info += {'bzip2 support': libbzip2}
3244 summary_info += {'lzfse support': liblzfse}
3245 summary_info += {'zstd support': zstd}
3246 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3247 summary_info += {'libxml2': libxml2}
3248 summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone}
3249 summary_info += {'libpmem support': libpmem}
3250 summary_info += {'libdaxctl support': libdaxctl}
3251 summary_info += {'libudev': libudev}
3252 # Dummy dependency, keep .found()
3253 summary_info += {'FUSE lseek': fuse_lseek.found()}
3254 summary(summary_info, bool_yn: true, section: 'Dependencies')
3256 if not supported_cpus.contains(cpu)
3258 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3260 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3261 message('The QEMU project intends to remove support for this host CPU in')
3262 message('a future release if nobody volunteers to maintain it and to')
3263 message('provide a build host for our continuous integration setup.')
3264 message('configure has succeeded and you can continue to build, but')
3265 message('if you care about QEMU on this platform you should contact')
3266 message('us upstream at qemu-devel@nongnu.org.')
3269 if not supported_oses.contains(targetos)
3271 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3273 message('Host OS ' + targetos + 'support is not currently maintained.')
3274 message('The QEMU project intends to remove support for this host OS in')
3275 message('a future release if nobody volunteers to maintain it and to')
3276 message('provide a build host for our continuous integration setup.')
3277 message('configure has succeeded and you can continue to build, but')
3278 message('if you care about QEMU on this platform you should contact')
3279 message('us upstream at qemu-devel@nongnu.org.')