target/arm: Use cpu_loop_exit_sigsegv for mte tag lookup
[qemu.git] / meson.build
blob90e3e85f20b671736b7b089d5aa7c1c52d70a52d
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',
3                           'b_staticpic=false'],
4         version: files('VERSION'))
6 not_found = dependency('', required: false)
7 keyval = import('keyval')
8 ss = import('sourceset')
9 fs = import('fs')
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 /')
29 endif
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()
40 genh = []
42 target_dirs = config_host['TARGET_DIRS'].split()
43 have_linux_user = false
44 have_bsd_user = false
45 have_system = false
46 foreach target : target_dirs
47   have_linux_user = have_linux_user or target.endswith('linux-user')
48   have_bsd_user = have_bsd_user or target.endswith('bsd-user')
49   have_system = have_system or target.endswith('-softmmu')
50 endforeach
51 have_user = have_linux_user or have_bsd_user
52 have_tools = 'CONFIG_TOOLS' in config_host
53 have_block = have_system or have_tools
55 python = import('python').find_installation()
57 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
58 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
59   'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
61 cpu = host_machine.cpu_family()
62 targetos = host_machine.system()
64 if cpu in ['x86', 'x86_64']
65   kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
66 elif cpu == 'aarch64'
67   kvm_targets = ['aarch64-softmmu']
68 elif cpu == 's390x'
69   kvm_targets = ['s390x-softmmu']
70 elif cpu in ['ppc', 'ppc64']
71   kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
72 elif cpu in ['mips', 'mips64']
73   kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
74 else
75   kvm_targets = []
76 endif
78 kvm_targets_c = ''
79 if not get_option('kvm').disabled() and targetos == 'linux'
80   kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
81 endif
82 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
84 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
86 if cpu in ['aarch64']
87   accelerator_targets += {
88     'CONFIG_HVF': ['aarch64-softmmu']
89   }
90 endif
92 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
93   # i386 emulator provides xenpv machine type for multiple architectures
94   accelerator_targets += {
95     'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
96   }
97 endif
98 if cpu in ['x86', 'x86_64']
99   accelerator_targets += {
100     'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
101     'CONFIG_HVF': ['x86_64-softmmu'],
102     'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
103     'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
104   }
105 endif
107 modular_tcg = []
108 # Darwin does not support references to thread-local variables in modules
109 if targetos != 'darwin'
110   modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
111 endif
113 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
114 unpack_edk2_blobs = false
115 foreach target : edk2_targets
116   if target in target_dirs
117     bzip2 = find_program('bzip2', required: get_option('install_blobs'))
118     unpack_edk2_blobs = bzip2.found()
119     break
120   endif
121 endforeach
123 dtrace = not_found
124 stap = not_found
125 if 'dtrace' in get_option('trace_backends')
126   dtrace = find_program('dtrace', required: true)
127   stap = find_program('stap', required: false)
128   if stap.found()
129     # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
130     # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
131     # instead. QEMU --enable-modules depends on this because the SystemTap
132     # semaphores are linked into the main binary and not the module's shared
133     # object.
134     add_global_arguments('-DSTAP_SDT_V2',
135                          native: false, language: ['c', 'cpp', 'objc'])
136   endif
137 endif
139 ##################
140 # Compiler flags #
141 ##################
143 # Specify linker-script with add_project_link_arguments so that it is not placed
144 # within a linker --start-group/--end-group pair
145 if get_option('fuzzing')
146   add_project_link_arguments(['-Wl,-T,',
147                               (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
148                              native: false, language: ['c', 'cpp', 'objc'])
150   # Specify a filter to only instrument code that is directly related to
151   # virtual-devices.
152   configure_file(output: 'instrumentation-filter',
153                  input: 'scripts/oss-fuzz/instrumentation-filter-template',
154                  copy: true)
155   add_global_arguments(
156       cc.get_supported_arguments('-fsanitize-coverage-allowlist=instrumentation-filter'),
157       native: false, language: ['c', 'cpp', 'objc'])
159   if get_option('fuzzing_engine') == ''
160     # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
161     # compiled code.  To build non-fuzzer binaries with --enable-fuzzing, link
162     # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
163     # unable to bind the fuzzer-related callbacks added by instrumentation.
164     add_global_arguments('-fsanitize=fuzzer-no-link',
165                          native: false, language: ['c', 'cpp', 'objc'])
166     add_global_link_arguments('-fsanitize=fuzzer-no-link',
167                               native: false, language: ['c', 'cpp', 'objc'])
168     # For the actual fuzzer binaries, we need to link against the libfuzzer
169     # library. They need to be configurable, to support OSS-Fuzz
170     fuzz_exe_ldflags = ['-fsanitize=fuzzer']
171   else
172     # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
173     # the needed CFLAGS have already been provided
174     fuzz_exe_ldflags = get_option('fuzzing_engine').split()
175   endif
176 endif
178 add_global_arguments(config_host['QEMU_CFLAGS'].split(),
179                      native: false, language: ['c', 'objc'])
180 add_global_arguments(config_host['QEMU_CXXFLAGS'].split(),
181                      native: false, language: 'cpp')
182 add_global_link_arguments(config_host['QEMU_LDFLAGS'].split(),
183                           native: false, language: ['c', 'cpp', 'objc'])
185 if targetos == 'linux'
186   add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
187                         '-isystem', 'linux-headers',
188                         language: ['c', 'cpp'])
189 endif
191 add_project_arguments('-iquote', '.',
192                       '-iquote', meson.current_source_dir(),
193                       '-iquote', meson.current_source_dir() / 'include',
194                       '-iquote', meson.current_source_dir() / 'disas/libvixl',
195                       language: ['c', 'cpp', 'objc'])
197 link_language = meson.get_external_property('link_language', 'cpp')
198 if link_language == 'cpp'
199   add_languages('cpp', required: true, native: false)
200 endif
201 if host_machine.system() == 'darwin'
202   add_languages('objc', required: false, native: false)
203 endif
205 sparse = find_program('cgcc', required: get_option('sparse'))
206 if sparse.found()
207   run_target('sparse',
208              command: [find_program('scripts/check_sparse.py'),
209                        'compile_commands.json', sparse.full_path(), '-Wbitwise',
210                        '-Wno-transparent-union', '-Wno-old-initializer',
211                        '-Wno-non-pointer-null'])
212 endif
214 ###########################################
215 # Target-specific checks and dependencies #
216 ###########################################
218 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
219     not cc.links('''
220           #include <stdint.h>
221           #include <sys/types.h>
222           int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
223           int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
224         ''',
225         args: ['-Werror', '-fsanitize=fuzzer'])
226   error('Your compiler does not support -fsanitize=fuzzer')
227 endif
229 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
230   error('ftrace is supported only on Linux')
231 endif
232 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
233     #include <syslog.h>
234     int main(void) {
235         openlog("qemu", LOG_PID, LOG_DAEMON);
236         syslog(LOG_INFO, "configure");
237         return 0;
238     }''')
239   error('syslog is not supported on this system')
240 endif
242 if targetos != 'linux' and get_option('mpath').enabled()
243   error('Multipath is supported only on Linux')
244 endif
246 if targetos != 'linux' and get_option('multiprocess').enabled()
247   error('Multiprocess QEMU is supported only on Linux')
248 endif
249 multiprocess_allowed = targetos == 'linux' and not get_option('multiprocess').disabled()
251 libm = cc.find_library('m', required: false)
252 threads = dependency('threads')
253 util = cc.find_library('util', required: false)
254 winmm = []
255 socket = []
256 version_res = []
257 coref = []
258 iokit = []
259 emulator_link_args = []
260 nvmm =not_found
261 hvf = not_found
262 host_dsosuf = '.so'
263 if targetos == 'windows'
264   socket = cc.find_library('ws2_32')
265   winmm = cc.find_library('winmm')
267   win = import('windows')
268   version_res = win.compile_resources('version.rc',
269                                       depend_files: files('pc-bios/qemu-nsis.ico'),
270                                       include_directories: include_directories('.'))
271   host_dsosuf = '.dll'
272 elif targetos == 'darwin'
273   coref = dependency('appleframeworks', modules: 'CoreFoundation')
274   iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
275   host_dsosuf = '.dylib'
276 elif targetos == 'sunos'
277   socket = [cc.find_library('socket'),
278             cc.find_library('nsl'),
279             cc.find_library('resolv')]
280 elif targetos == 'haiku'
281   socket = [cc.find_library('posix_error_mapper'),
282             cc.find_library('network'),
283             cc.find_library('bsd')]
284 elif targetos == 'openbsd'
285   if not get_option('tcg').disabled() and target_dirs.length() > 0
286     # Disable OpenBSD W^X if available
287     emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
288   endif
289 endif
291 accelerators = []
292 if not get_option('kvm').disabled() and targetos == 'linux'
293   accelerators += 'CONFIG_KVM'
294 endif
295 if not get_option('xen').disabled() and 'CONFIG_XEN_BACKEND' in config_host
296   accelerators += 'CONFIG_XEN'
297   have_xen_pci_passthrough = not get_option('xen_pci_passthrough').disabled() and targetos == 'linux'
298 else
299   have_xen_pci_passthrough = false
300 endif
301 if not get_option('whpx').disabled() and targetos == 'windows'
302   if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
303     error('WHPX requires 64-bit host')
304   elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
305        cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
306     accelerators += 'CONFIG_WHPX'
307   endif
308 endif
309 if not get_option('hvf').disabled()
310   hvf = dependency('appleframeworks', modules: 'Hypervisor',
311                    required: get_option('hvf'))
312   if hvf.found()
313     accelerators += 'CONFIG_HVF'
314   endif
315 endif
316 if not get_option('hax').disabled()
317   if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
318     accelerators += 'CONFIG_HAX'
319   endif
320 endif
321 if targetos == 'netbsd'
322   if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
323     nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
324   endif
325   if nvmm.found()
326     accelerators += 'CONFIG_NVMM'
327   endif
328 endif
330 tcg_arch = config_host['ARCH']
331 if not get_option('tcg').disabled()
332   if cpu not in supported_cpus
333     if get_option('tcg_interpreter')
334       warning('Unsupported CPU @0@, will use TCG with TCI (experimental and slow)'.format(cpu))
335     else
336       error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
337     endif
338   elif get_option('tcg_interpreter')
339     warning('Use of the TCG interpretor is not recommended on this host')
340     warning('architecture. There is a native TCG execution backend available')
341     warning('which provides substantially better performance and reliability.')
342     warning('It is strongly recommended to remove the --enable-tcg-interpreter')
343     warning('configuration option on this architecture to use the native')
344     warning('backend.')
345   endif
346   if get_option('tcg_interpreter')
347     tcg_arch = 'tci'
348   elif config_host['ARCH'] == 'sparc64'
349     tcg_arch = 'sparc'
350   elif config_host['ARCH'] in ['x86_64', 'x32']
351     tcg_arch = 'i386'
352   elif config_host['ARCH'] == 'ppc64'
353     tcg_arch = 'ppc'
354   endif
355   add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
356                         language: ['c', 'cpp', 'objc'])
358   accelerators += 'CONFIG_TCG'
359   config_host += { 'CONFIG_TCG': 'y' }
360 endif
362 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
363   error('KVM not available on this platform')
364 endif
365 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
366   error('HVF not available on this platform')
367 endif
368 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
369   error('NVMM not available on this platform')
370 endif
371 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
372   error('WHPX not available on this platform')
373 endif
374 if not have_xen_pci_passthrough and get_option('xen_pci_passthrough').enabled()
375   if 'CONFIG_XEN' in accelerators
376     error('Xen PCI passthrough not available on this platform')
377   else
378     error('Xen PCI passthrough requested but Xen not enabled')
379   endif
380 endif
382 ################
383 # Dependencies #
384 ################
386 # The path to glib.h is added to all compilation commands.  This was
387 # grandfathered in from the QEMU Makefiles.
388 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
389                       native: false, language: ['c', 'cpp', 'objc'])
390 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
391                           link_args: config_host['GLIB_LIBS'].split())
392 # override glib dep with the configure results (for subprojects)
393 meson.override_dependency('glib-2.0', glib)
395 gio = not_found
396 if 'CONFIG_GIO' in config_host
397   gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
398                            link_args: config_host['GIO_LIBS'].split())
399 endif
400 lttng = not_found
401 if 'ust' in get_option('trace_backends')
402   lttng = dependency('lttng-ust', required: true, method: 'pkg-config',
403                      kwargs: static_kwargs)
404 endif
405 pixman = not_found
406 if have_system or have_tools
407   pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
408                       method: 'pkg-config', kwargs: static_kwargs)
409 endif
410 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
412 libaio = not_found
413 if not get_option('linux_aio').auto() or have_block
414   libaio = cc.find_library('aio', has_headers: ['libaio.h'],
415                            required: get_option('linux_aio'),
416                            kwargs: static_kwargs)
417 endif
418 linux_io_uring = not_found
419 if not get_option('linux_io_uring').auto() or have_block
420   linux_io_uring = dependency('liburing', required: get_option('linux_io_uring'),
421                               method: 'pkg-config', kwargs: static_kwargs)
422 endif
423 libxml2 = not_found
424 if not get_option('libxml2').auto() or have_block
425   libxml2 = dependency('libxml-2.0', required: get_option('libxml2'),
426                        method: 'pkg-config', kwargs: static_kwargs)
427 endif
428 libnfs = not_found
429 if not get_option('libnfs').auto() or have_block
430   libnfs = dependency('libnfs', version: '>=1.9.3',
431                       required: get_option('libnfs'),
432                       method: 'pkg-config', kwargs: static_kwargs)
433 endif
435 libattr_test = '''
436   #include <stddef.h>
437   #include <sys/types.h>
438   #ifdef CONFIG_LIBATTR
439   #include <attr/xattr.h>
440   #else
441   #include <sys/xattr.h>
442   #endif
443   int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
445 libattr = not_found
446 have_old_libattr = false
447 if not get_option('attr').disabled()
448   if cc.links(libattr_test)
449     libattr = declare_dependency()
450   else
451     libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
452                               required: get_option('attr'),
453                               kwargs: static_kwargs)
454     if libattr.found() and not \
455       cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
456       libattr = not_found
457       if get_option('attr').enabled()
458         error('could not link libattr')
459       else
460         warning('could not link libattr, disabling')
461       endif
462     else
463       have_old_libattr = libattr.found()
464     endif
465   endif
466 endif
468 cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
469 if cocoa.found() and get_option('sdl').enabled()
470   error('Cocoa and SDL cannot be enabled at the same time')
471 endif
472 if cocoa.found() and get_option('gtk').enabled()
473   error('Cocoa and GTK+ cannot be enabled at the same time')
474 endif
476 seccomp = not_found
477 if not get_option('seccomp').auto() or have_system or have_tools
478   seccomp = dependency('libseccomp', version: '>=2.3.0',
479                        required: get_option('seccomp'),
480                        method: 'pkg-config', kwargs: static_kwargs)
481 endif
483 libcap_ng = not_found
484 if not get_option('cap_ng').auto() or have_system or have_tools
485   libcap_ng = cc.find_library('cap-ng', has_headers: ['cap-ng.h'],
486                               required: get_option('cap_ng'),
487                               kwargs: static_kwargs)
488 endif
489 if libcap_ng.found() and not cc.links('''
490    #include <cap-ng.h>
491    int main(void)
492    {
493      capng_capability_to_name(CAPNG_EFFECTIVE);
494      return 0;
495    }''', dependencies: libcap_ng)
496   libcap_ng = not_found
497   if get_option('cap_ng').enabled()
498     error('could not link libcap-ng')
499   else
500     warning('could not link libcap-ng, disabling')
501   endif
502 endif
504 if get_option('xkbcommon').auto() and not have_system and not have_tools
505   xkbcommon = not_found
506 else
507   xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'),
508                          method: 'pkg-config', kwargs: static_kwargs)
509 endif
511 vde = not_found
512 if not get_option('vde').auto() or have_system or have_tools
513   vde = cc.find_library('vdeplug', has_headers: ['libvdeplug.h'],
514                            required: get_option('vde'),
515                            kwargs: static_kwargs)
516 endif
517 if vde.found() and not cc.links('''
518    #include <libvdeplug.h>
519    int main(void)
520    {
521      struct vde_open_args a = {0, 0, 0};
522      char s[] = "";
523      vde_open(s, s, &a);
524      return 0;
525    }''', dependencies: vde)
526   vde = not_found
527   if get_option('cap_ng').enabled()
528     error('could not link libvdeplug')
529   else
530     warning('could not link libvdeplug, disabling')
531   endif
532 endif
534 pulse = not_found
535 if not get_option('pa').auto() or (targetos == 'linux' and have_system)
536   pulse = dependency('libpulse', required: get_option('pa'),
537                      method: 'pkg-config', kwargs: static_kwargs)
538 endif
539 alsa = not_found
540 if not get_option('alsa').auto() or (targetos == 'linux' and have_system)
541   alsa = dependency('alsa', required: get_option('alsa'),
542                     method: 'pkg-config', kwargs: static_kwargs)
543 endif
544 jack = not_found
545 if not get_option('jack').auto() or have_system
546   jack = dependency('jack', required: get_option('jack'),
547                     method: 'pkg-config', kwargs: static_kwargs)
548 endif
550 spice_protocol = not_found
551 if not get_option('spice_protocol').auto() or have_system
552   spice_protocol = dependency('spice-protocol', version: '>=0.12.3',
553                               required: get_option('spice_protocol'),
554                               method: 'pkg-config', kwargs: static_kwargs)
555 endif
556 spice = not_found
557 if not get_option('spice').auto() or have_system
558   spice = dependency('spice-server', version: '>=0.12.5',
559                      required: get_option('spice'),
560                      method: 'pkg-config', kwargs: static_kwargs)
561 endif
562 spice_headers = spice.partial_dependency(compile_args: true, includes: true)
564 rt = cc.find_library('rt', required: false)
565 libdl = not_found
566 if 'CONFIG_PLUGIN' in config_host
567   libdl = cc.find_library('dl', required: false)
568   if not cc.has_function('dlopen', dependencies: libdl)
569     error('dlopen not found')
570   endif
571 endif
572 libiscsi = not_found
573 if not get_option('libiscsi').auto() or have_block
574   libiscsi = dependency('libiscsi', version: '>=1.9.0',
575                          required: get_option('libiscsi'),
576                          method: 'pkg-config', kwargs: static_kwargs)
577 endif
578 zstd = not_found
579 if not get_option('zstd').auto() or have_block
580   zstd = dependency('libzstd', version: '>=1.4.0',
581                     required: get_option('zstd'),
582                     method: 'pkg-config', kwargs: static_kwargs)
583 endif
584 virgl = not_found
585 if not get_option('virglrenderer').auto() or have_system
586   virgl = dependency('virglrenderer',
587                      method: 'pkg-config',
588                      required: get_option('virglrenderer'),
589                      kwargs: static_kwargs)
590 endif
591 curl = not_found
592 if not get_option('curl').auto() or have_block
593   curl = dependency('libcurl', version: '>=7.29.0',
594                     method: 'pkg-config',
595                     required: get_option('curl'),
596                     kwargs: static_kwargs)
597 endif
598 libudev = not_found
599 if targetos == 'linux' and (have_system or have_tools)
600   libudev = dependency('libudev',
601                        method: 'pkg-config',
602                        required: get_option('libudev'),
603                        kwargs: static_kwargs)
604 endif
606 mpathlibs = [libudev]
607 mpathpersist = not_found
608 mpathpersist_new_api = false
609 if targetos == 'linux' and have_tools and not get_option('mpath').disabled()
610   mpath_test_source_new = '''
611     #include <libudev.h>
612     #include <mpath_persist.h>
613     unsigned mpath_mx_alloc_len = 1024;
614     int logsink;
615     static struct config *multipath_conf;
616     extern struct udev *udev;
617     extern struct config *get_multipath_config(void);
618     extern void put_multipath_config(struct config *conf);
619     struct udev *udev;
620     struct config *get_multipath_config(void) { return multipath_conf; }
621     void put_multipath_config(struct config *conf) { }
622     int main(void) {
623         udev = udev_new();
624         multipath_conf = mpath_lib_init();
625         return 0;
626     }'''
627   mpath_test_source_old = '''
628       #include <libudev.h>
629       #include <mpath_persist.h>
630       unsigned mpath_mx_alloc_len = 1024;
631       int logsink;
632       int main(void) {
633           struct udev *udev = udev_new();
634           mpath_lib_init(udev);
635           return 0;
636       }'''
637   libmpathpersist = cc.find_library('mpathpersist',
638                                     required: get_option('mpath'),
639                                     kwargs: static_kwargs)
640   if libmpathpersist.found()
641     mpathlibs += libmpathpersist
642     if enable_static
643       mpathlibs += cc.find_library('devmapper',
644                                      required: get_option('mpath'),
645                                      kwargs: static_kwargs)
646     endif
647     mpathlibs += cc.find_library('multipath',
648                                  required: get_option('mpath'),
649                                  kwargs: static_kwargs)
650     foreach lib: mpathlibs
651       if not lib.found()
652         mpathlibs = []
653         break
654       endif
655     endforeach
656     if mpathlibs.length() == 0
657       msg = 'Dependencies missing for libmpathpersist'
658     elif cc.links(mpath_test_source_new, dependencies: mpathlibs)
659       mpathpersist = declare_dependency(dependencies: mpathlibs)
660       mpathpersist_new_api = true
661     elif cc.links(mpath_test_source_old, dependencies: mpathlibs)
662       mpathpersist = declare_dependency(dependencies: mpathlibs)
663     else
664       msg = 'Cannot detect libmpathpersist API'
665     endif
666     if not mpathpersist.found()
667       if get_option('mpath').enabled()
668         error(msg)
669       else
670         warning(msg + ', disabling')
671       endif
672     endif
673   endif
674 endif
676 iconv = not_found
677 curses = not_found
678 if have_system and not get_option('curses').disabled()
679   curses_test = '''
680     #include <locale.h>
681     #include <curses.h>
682     #include <wchar.h>
683     int main(void) {
684       wchar_t wch = L'w';
685       setlocale(LC_ALL, "");
686       resize_term(0, 0);
687       addwstr(L"wide chars\n");
688       addnwstr(&wch, 1);
689       add_wch(WACS_DEGREE);
690       return 0;
691     }'''
693   curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
694   foreach curses_dep : curses_dep_list
695     if not curses.found()
696       curses = dependency(curses_dep,
697                           required: false,
698                           method: 'pkg-config',
699                           kwargs: static_kwargs)
700     endif
701   endforeach
702   msg = get_option('curses').enabled() ? 'curses library not found' : ''
703   curses_compile_args = ['-DNCURSES_WIDECHAR']
704   if curses.found()
705     if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
706       curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
707     else
708       msg = 'curses package not usable'
709       curses = not_found
710     endif
711   endif
712   if not curses.found()
713     has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
714     if targetos != 'windows' and not has_curses_h
715       message('Trying with /usr/include/ncursesw')
716       curses_compile_args += ['-I/usr/include/ncursesw']
717       has_curses_h = cc.has_header('curses.h', args: curses_compile_args)
718     endif
719     if has_curses_h
720       curses_libname_list = (targetos == 'windows' ? ['pdcurses'] : ['ncursesw', 'cursesw'])
721       foreach curses_libname : curses_libname_list
722         libcurses = cc.find_library(curses_libname,
723                                     required: false,
724                                     kwargs: static_kwargs)
725         if libcurses.found()
726           if cc.links(curses_test, args: curses_compile_args, dependencies: libcurses)
727             curses = declare_dependency(compile_args: curses_compile_args,
728                                         dependencies: [libcurses])
729             break
730           else
731             msg = 'curses library not usable'
732           endif
733         endif
734       endforeach
735     endif
736   endif
737   if not get_option('iconv').disabled()
738     foreach link_args : [ ['-liconv'], [] ]
739       # Programs will be linked with glib and this will bring in libiconv on FreeBSD.
740       # We need to use libiconv if available because mixing libiconv's headers with
741       # the system libc does not work.
742       # However, without adding glib to the dependencies -L/usr/local/lib will not be
743       # included in the command line and libiconv will not be found.
744       if cc.links('''
745         #include <iconv.h>
746         int main(void) {
747           iconv_t conv = iconv_open("WCHAR_T", "UCS-2");
748           return conv != (iconv_t) -1;
749         }''', args: config_host['GLIB_CFLAGS'].split() + config_host['GLIB_LIBS'].split() + link_args)
750         iconv = declare_dependency(link_args: link_args, dependencies: glib)
751         break
752       endif
753     endforeach
754   endif
755   if curses.found() and not iconv.found()
756     if get_option('iconv').enabled()
757       error('iconv not available')
758     endif
759     msg = 'iconv required for curses UI but not available'
760     curses = not_found
761   endif
762   if not curses.found() and msg != ''
763     if get_option('curses').enabled()
764       error(msg)
765     else
766       warning(msg + ', disabling')
767     endif
768   endif
769 endif
771 brlapi = not_found
772 if not get_option('brlapi').auto() or have_system
773   brlapi = cc.find_library('brlapi', has_headers: ['brlapi.h'],
774                          required: get_option('brlapi'),
775                          kwargs: static_kwargs)
776   if brlapi.found() and not cc.links('''
777      #include <brlapi.h>
778      #include <stddef.h>
779      int main(void) { return brlapi__openConnection (NULL, NULL, NULL); }''', dependencies: brlapi)
780     brlapi = not_found
781     if get_option('brlapi').enabled()
782       error('could not link brlapi')
783     else
784       warning('could not link brlapi, disabling')
785     endif
786   endif
787 endif
789 sdl = not_found
790 if not get_option('sdl').auto() or (have_system and not cocoa.found())
791   sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
792   sdl_image = not_found
793 endif
794 if sdl.found()
795   # work around 2.0.8 bug
796   sdl = declare_dependency(compile_args: '-Wno-undef',
797                            dependencies: sdl)
798   sdl_image = dependency('SDL2_image', required: get_option('sdl_image'),
799                          method: 'pkg-config', kwargs: static_kwargs)
800 else
801   if get_option('sdl_image').enabled()
802     error('sdl-image required, but SDL was @0@'.format(
803           get_option('sdl').disabled() ? 'disabled' : 'not found'))
804   endif
805   sdl_image = not_found
806 endif
808 rbd = not_found
809 if not get_option('rbd').auto() or have_block
810   librados = cc.find_library('rados', required: get_option('rbd'),
811                              kwargs: static_kwargs)
812   librbd = cc.find_library('rbd', has_headers: ['rbd/librbd.h'],
813                            required: get_option('rbd'),
814                            kwargs: static_kwargs)
815   if librados.found() and librbd.found()
816     if cc.links('''
817       #include <stdio.h>
818       #include <rbd/librbd.h>
819       int main(void) {
820         rados_t cluster;
821         rados_create(&cluster, NULL);
822         #if LIBRBD_VERSION_CODE < LIBRBD_VERSION(1, 12, 0)
823         #error
824         #endif
825         return 0;
826       }''', dependencies: [librbd, librados])
827       rbd = declare_dependency(dependencies: [librbd, librados])
828     elif get_option('rbd').enabled()
829       error('librbd >= 1.12.0 required')
830     else
831       warning('librbd >= 1.12.0 not found, disabling')
832     endif
833   endif
834 endif
836 glusterfs = not_found
837 glusterfs_ftruncate_has_stat = false
838 glusterfs_iocb_has_stat = false
839 if not get_option('glusterfs').auto() or have_block
840   glusterfs = dependency('glusterfs-api', version: '>=3',
841                          required: get_option('glusterfs'),
842                          method: 'pkg-config', kwargs: static_kwargs)
843   if glusterfs.found()
844     glusterfs_ftruncate_has_stat = cc.links('''
845       #include <glusterfs/api/glfs.h>
847       int
848       main(void)
849       {
850           /* new glfs_ftruncate() passes two additional args */
851           return glfs_ftruncate(NULL, 0, NULL, NULL);
852       }
853     ''', dependencies: glusterfs)
854     glusterfs_iocb_has_stat = cc.links('''
855       #include <glusterfs/api/glfs.h>
857       /* new glfs_io_cbk() passes two additional glfs_stat structs */
858       static void
859       glusterfs_iocb(glfs_fd_t *fd, ssize_t ret, struct glfs_stat *prestat, struct glfs_stat *poststat, void *data)
860       {}
862       int
863       main(void)
864       {
865           glfs_io_cbk iocb = &glusterfs_iocb;
866           iocb(NULL, 0 , NULL, NULL, NULL);
867           return 0;
868       }
869     ''', dependencies: glusterfs)
870   endif
871 endif
872 libssh = not_found
873 if 'CONFIG_LIBSSH' in config_host
874   libssh = declare_dependency(compile_args: config_host['LIBSSH_CFLAGS'].split(),
875                               link_args: config_host['LIBSSH_LIBS'].split())
876 endif
877 libbzip2 = not_found
878 if not get_option('bzip2').auto() or have_block
879   libbzip2 = cc.find_library('bz2', has_headers: ['bzlib.h'],
880                              required: get_option('bzip2'),
881                              kwargs: static_kwargs)
882   if libbzip2.found() and not cc.links('''
883      #include <bzlib.h>
884      int main(void) { BZ2_bzlibVersion(); return 0; }''', dependencies: libbzip2)
885     libbzip2 = not_found
886     if get_option('bzip2').enabled()
887       error('could not link libbzip2')
888     else
889       warning('could not link libbzip2, disabling')
890     endif
891   endif
892 endif
894 liblzfse = not_found
895 if not get_option('lzfse').auto() or have_block
896   liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'],
897                              required: get_option('lzfse'),
898                              kwargs: static_kwargs)
899 endif
900 if liblzfse.found() and not cc.links('''
901    #include <lzfse.h>
902    int main(void) { lzfse_decode_scratch_size(); return 0; }''', dependencies: liblzfse)
903   liblzfse = not_found
904   if get_option('lzfse').enabled()
905     error('could not link liblzfse')
906   else
907     warning('could not link liblzfse, disabling')
908   endif
909 endif
911 oss = not_found
912 if not get_option('oss').auto() or have_system
913   if not cc.has_header('sys/soundcard.h')
914     # not found
915   elif targetos == 'netbsd'
916     oss = cc.find_library('ossaudio', required: get_option('oss'),
917                           kwargs: static_kwargs)
918   else
919     oss = declare_dependency()
920   endif
922   if not oss.found()
923     if get_option('oss').enabled()
924       error('OSS not found')
925     else
926       warning('OSS not found, disabling')
927     endif
928   endif
929 endif
930 dsound = not_found
931 if not get_option('dsound').auto() or (targetos == 'windows' and have_system)
932   if cc.has_header('dsound.h')
933     dsound = declare_dependency(link_args: ['-lole32', '-ldxguid'])
934   endif
936   if not dsound.found()
937     if get_option('dsound').enabled()
938       error('DirectSound not found')
939     else
940       warning('DirectSound not found, disabling')
941     endif
942   endif
943 endif
945 coreaudio = not_found
946 if not get_option('coreaudio').auto() or (targetos == 'darwin' and have_system)
947   coreaudio = dependency('appleframeworks', modules: 'CoreAudio',
948                          required: get_option('coreaudio'))
949   if coreaudio.found() and not cc.links('''
950     #include <CoreAudio/CoreAudio.h>
951     int main(void)
952     {
953       return (int)AudioGetCurrentHostTime();
954     }''')
955     coreaudio = not_found
956   endif
958   if not coreaudio.found()
959     if get_option('coreaudio').enabled()
960       error('CoreAudio not found')
961     else
962       warning('CoreAudio not found, disabling')
963     endif
964   endif
965 endif
967 opengl = not_found
968 if 'CONFIG_OPENGL' in config_host
969   opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
970                               link_args: config_host['OPENGL_LIBS'].split())
971 endif
972 gbm = not_found
973 if (have_system or have_tools) and (virgl.found() or opengl.found())
974   gbm = dependency('gbm', method: 'pkg-config', required: false,
975                    kwargs: static_kwargs)
976 endif
978 gnutls = not_found
979 gnutls_crypto = not_found
980 if get_option('gnutls').enabled() or (get_option('gnutls').auto() and have_system)
981   # For general TLS support our min gnutls matches
982   # that implied by our platform support matrix
983   #
984   # For the crypto backends, we look for a newer
985   # gnutls:
986   #
987   #   Version 3.6.8  is needed to get XTS
988   #   Version 3.6.13 is needed to get PBKDF
989   #   Version 3.6.14 is needed to get HW accelerated XTS
990   #
991   # If newer enough gnutls isn't available, we can
992   # still use a different crypto backend to satisfy
993   # the platform support requirements
994   gnutls_crypto = dependency('gnutls', version: '>=3.6.14',
995                              method: 'pkg-config',
996                              required: false,
997                              kwargs: static_kwargs)
998   if gnutls_crypto.found()
999     gnutls = gnutls_crypto
1000   else
1001     # Our min version if all we need is TLS
1002     gnutls = dependency('gnutls', version: '>=3.5.18',
1003                         method: 'pkg-config',
1004                         required: get_option('gnutls'),
1005                         kwargs: static_kwargs)
1006   endif
1007 endif
1009 # We prefer use of gnutls for crypto, unless the options
1010 # explicitly asked for nettle or gcrypt.
1012 # If gnutls isn't available for crypto, then we'll prefer
1013 # gcrypt over nettle for performance reasons.
1014 gcrypt = not_found
1015 nettle = not_found
1016 xts = 'none'
1018 if get_option('nettle').enabled() and get_option('gcrypt').enabled()
1019   error('Only one of gcrypt & nettle can be enabled')
1020 endif
1022 # Explicit nettle/gcrypt request, so ignore gnutls for crypto
1023 if get_option('nettle').enabled() or get_option('gcrypt').enabled()
1024   gnutls_crypto = not_found
1025 endif
1027 if not gnutls_crypto.found()
1028   if (not get_option('gcrypt').auto() or have_system) and not get_option('nettle').enabled()
1029     gcrypt = dependency('libgcrypt', version: '>=1.8',
1030                         method: 'config-tool',
1031                         required: get_option('gcrypt'),
1032                         kwargs: static_kwargs)
1033     # Debian has removed -lgpg-error from libgcrypt-config
1034     # as it "spreads unnecessary dependencies" which in
1035     # turn breaks static builds...
1036     if gcrypt.found() and enable_static
1037       gcrypt = declare_dependency(dependencies: [
1038         gcrypt,
1039         cc.find_library('gpg-error', required: true, kwargs: static_kwargs)])
1040     endif
1041   endif
1042   if (not get_option('nettle').auto() or have_system) and not gcrypt.found()
1043     nettle = dependency('nettle', version: '>=3.4',
1044                         method: 'pkg-config',
1045                         required: get_option('nettle'),
1046                         kwargs: static_kwargs)
1047     if nettle.found() and not cc.has_header('nettle/xts.h', dependencies: nettle)
1048       xts = 'private'
1049     endif
1050   endif
1051 endif
1053 gtk = not_found
1054 gtkx11 = not_found
1055 vte = not_found
1056 if not get_option('gtk').auto() or (have_system and not cocoa.found())
1057   gtk = dependency('gtk+-3.0', version: '>=3.22.0',
1058                    method: 'pkg-config',
1059                    required: get_option('gtk'),
1060                    kwargs: static_kwargs)
1061   if gtk.found()
1062     gtkx11 = dependency('gtk+-x11-3.0', version: '>=3.22.0',
1063                         method: 'pkg-config',
1064                         required: false,
1065                         kwargs: static_kwargs)
1066     gtk = declare_dependency(dependencies: [gtk, gtkx11])
1068     if not get_option('vte').auto() or have_system
1069       vte = dependency('vte-2.91',
1070                        method: 'pkg-config',
1071                        required: get_option('vte'),
1072                        kwargs: static_kwargs)
1073     endif
1074   endif
1075 endif
1077 x11 = not_found
1078 if gtkx11.found()
1079   x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
1080                    kwargs: static_kwargs)
1081 endif
1082 vnc = not_found
1083 png = not_found
1084 jpeg = not_found
1085 sasl = not_found
1086 if have_system and not get_option('vnc').disabled()
1087   vnc = declare_dependency() # dummy dependency
1088   png = dependency('libpng', required: get_option('vnc_png'),
1089                    method: 'pkg-config', kwargs: static_kwargs)
1090   jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
1091                     method: 'pkg-config', kwargs: static_kwargs)
1092   sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
1093                          required: get_option('vnc_sasl'),
1094                          kwargs: static_kwargs)
1095   if sasl.found()
1096     sasl = declare_dependency(dependencies: sasl,
1097                               compile_args: '-DSTRUCT_IOVEC_DEFINED')
1098   endif
1099 endif
1101 pam = not_found
1102 if not get_option('auth_pam').auto() or have_system
1103   pam = cc.find_library('pam', has_headers: ['security/pam_appl.h'],
1104                         required: get_option('auth_pam'),
1105                         kwargs: static_kwargs)
1106 endif
1107 if pam.found() and not cc.links('''
1108    #include <stddef.h>
1109    #include <security/pam_appl.h>
1110    int main(void) {
1111      const char *service_name = "qemu";
1112      const char *user = "frank";
1113      const struct pam_conv pam_conv = { 0 };
1114      pam_handle_t *pamh = NULL;
1115      pam_start(service_name, user, &pam_conv, &pamh);
1116      return 0;
1117    }''', dependencies: pam)
1118   pam = not_found
1119   if get_option('auth_pam').enabled()
1120     error('could not link libpam')
1121   else
1122     warning('could not link libpam, disabling')
1123   endif
1124 endif
1126 snappy = not_found
1127 if not get_option('snappy').auto() or have_system
1128   snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'],
1129                            required: get_option('snappy'),
1130                            kwargs: static_kwargs)
1131 endif
1132 if snappy.found() and not cc.links('''
1133    #include <snappy-c.h>
1134    int main(void) { snappy_max_compressed_length(4096); return 0; }''', dependencies: snappy)
1135   snappy = not_found
1136   if get_option('snappy').enabled()
1137     error('could not link libsnappy')
1138   else
1139     warning('could not link libsnappy, disabling')
1140   endif
1141 endif
1143 lzo = not_found
1144 if not get_option('lzo').auto() or have_system
1145   lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'],
1146                         required: get_option('lzo'),
1147                         kwargs: static_kwargs)
1148 endif
1149 if lzo.found() and not cc.links('''
1150    #include <lzo/lzo1x.h>
1151    int main(void) { lzo_version(); return 0; }''', dependencies: lzo)
1152   lzo = not_found
1153   if get_option('lzo').enabled()
1154     error('could not link liblzo2')
1155   else
1156     warning('could not link liblzo2, disabling')
1157   endif
1158 endif
1160 rdma = not_found
1161 if 'CONFIG_RDMA' in config_host
1162   rdma = declare_dependency(link_args: config_host['RDMA_LIBS'].split())
1163 endif
1164 numa = not_found
1165 if 'CONFIG_NUMA' in config_host
1166   numa = declare_dependency(link_args: config_host['NUMA_LIBS'].split())
1167 endif
1168 xen = not_found
1169 if 'CONFIG_XEN_BACKEND' in config_host
1170   xen = declare_dependency(compile_args: config_host['XEN_CFLAGS'].split(),
1171                            link_args: config_host['XEN_LIBS'].split())
1172 endif
1173 cacard = not_found
1174 if not get_option('smartcard').auto() or have_system
1175   cacard = dependency('libcacard', required: get_option('smartcard'),
1176                       version: '>=2.5.1', method: 'pkg-config',
1177                       kwargs: static_kwargs)
1178 endif
1179 u2f = not_found
1180 if have_system
1181   u2f = dependency('u2f-emu', required: get_option('u2f'),
1182                    method: 'pkg-config',
1183                    kwargs: static_kwargs)
1184 endif
1185 usbredir = not_found
1186 if not get_option('usb_redir').auto() or have_system
1187   usbredir = dependency('libusbredirparser-0.5', required: get_option('usb_redir'),
1188                         version: '>=0.6', method: 'pkg-config',
1189                         kwargs: static_kwargs)
1190 endif
1191 libusb = not_found
1192 if not get_option('libusb').auto() or have_system
1193   libusb = dependency('libusb-1.0', required: get_option('libusb'),
1194                       version: '>=1.0.13', method: 'pkg-config',
1195                       kwargs: static_kwargs)
1196 endif
1198 libpmem = not_found
1199 if not get_option('libpmem').auto() or have_system
1200   libpmem = dependency('libpmem', required: get_option('libpmem'),
1201                        method: 'pkg-config', kwargs: static_kwargs)
1202 endif
1203 libdaxctl = not_found
1204 if not get_option('libdaxctl').auto() or have_system
1205   libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'),
1206                          version: '>=57', method: 'pkg-config',
1207                          kwargs: static_kwargs)
1208 endif
1209 tasn1 = not_found
1210 if gnutls.found()
1211   tasn1 = dependency('libtasn1',
1212                      method: 'pkg-config',
1213                      kwargs: static_kwargs)
1214 endif
1215 keyutils = dependency('libkeyutils', required: false,
1216                       method: 'pkg-config', kwargs: static_kwargs)
1218 has_gettid = cc.has_function('gettid')
1220 # Malloc tests
1222 malloc = []
1223 if get_option('malloc') == 'system'
1224   has_malloc_trim = \
1225     not get_option('malloc_trim').disabled() and \
1226     cc.links('''#include <malloc.h>
1227                 int main(void) { malloc_trim(0); return 0; }''')
1228 else
1229   has_malloc_trim = false
1230   malloc = cc.find_library(get_option('malloc'), required: true)
1231 endif
1232 if not has_malloc_trim and get_option('malloc_trim').enabled()
1233   if get_option('malloc') == 'system'
1234     error('malloc_trim not available on this platform.')
1235   else
1236     error('malloc_trim not available with non-libc memory allocator')
1237   endif
1238 endif
1240 # Check whether the glibc provides statx()
1242 gnu_source_prefix = '''
1243   #ifndef _GNU_SOURCE
1244   #define _GNU_SOURCE
1245   #endif
1247 statx_test = gnu_source_prefix + '''
1248   #include <sys/stat.h>
1249   int main(void) {
1250     struct statx statxbuf;
1251     statx(0, "", 0, STATX_BASIC_STATS, &statxbuf);
1252     return 0;
1253   }'''
1255 has_statx = cc.links(statx_test)
1257 have_vhost_user_blk_server = (targetos == 'linux' and
1258     'CONFIG_VHOST_USER' in config_host)
1260 if get_option('vhost_user_blk_server').enabled()
1261     if targetos != 'linux'
1262         error('vhost_user_blk_server requires linux')
1263     elif 'CONFIG_VHOST_USER' not in config_host
1264         error('vhost_user_blk_server requires vhost-user support')
1265     endif
1266 elif get_option('vhost_user_blk_server').disabled() or not have_system
1267     have_vhost_user_blk_server = false
1268 endif
1271 if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
1272   error('Cannot enable fuse-lseek while fuse is disabled')
1273 endif
1275 fuse = dependency('fuse3', required: get_option('fuse'),
1276                   version: '>=3.1', method: 'pkg-config',
1277                   kwargs: static_kwargs)
1279 fuse_lseek = not_found
1280 if not get_option('fuse_lseek').disabled()
1281   if fuse.version().version_compare('>=3.8')
1282     # Dummy dependency
1283     fuse_lseek = declare_dependency()
1284   elif get_option('fuse_lseek').enabled()
1285     if fuse.found()
1286       error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version())
1287     else
1288       error('fuse-lseek requires libfuse, which was not found')
1289     endif
1290   endif
1291 endif
1293 # libbpf
1294 libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1295 if libbpf.found() and not cc.links('''
1296    #include <bpf/libbpf.h>
1297    int main(void)
1298    {
1299      bpf_object__destroy_skeleton(NULL);
1300      return 0;
1301    }''', dependencies: libbpf)
1302   libbpf = not_found
1303   if get_option('bpf').enabled()
1304     error('libbpf skeleton test failed')
1305   else
1306     warning('libbpf skeleton test failed, disabling')
1307   endif
1308 endif
1310 #################
1311 # config-host.h #
1312 #################
1314 audio_drivers_selected = []
1315 if have_system
1316   audio_drivers_available = {
1317     'alsa': alsa.found(),
1318     'coreaudio': coreaudio.found(),
1319     'dsound': dsound.found(),
1320     'jack': jack.found(),
1321     'oss': oss.found(),
1322     'pa': pulse.found(),
1323     'sdl': sdl.found(),
1324   }
1325   foreach k, v: audio_drivers_available
1326     config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
1327   endforeach
1329   # Default to native drivers first, OSS second, SDL third
1330   audio_drivers_priority = \
1331     [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
1332     (targetos == 'linux' ? [] : [ 'sdl' ])
1333   audio_drivers_default = []
1334   foreach k: audio_drivers_priority
1335     if audio_drivers_available[k]
1336       audio_drivers_default += k
1337     endif
1338   endforeach
1340   foreach k: get_option('audio_drv_list')
1341     if k == 'default'
1342       audio_drivers_selected += audio_drivers_default
1343     elif not audio_drivers_available[k]
1344       error('Audio driver "@0@" not available.'.format(k))
1345     else
1346       audio_drivers_selected += k
1347     endif
1348   endforeach
1349 endif
1350 config_host_data.set('CONFIG_AUDIO_DRIVERS',
1351                      '"' + '", "'.join(audio_drivers_selected) + '", ')
1353 if get_option('cfi')
1354   cfi_flags=[]
1355   # Check for dependency on LTO
1356   if not get_option('b_lto')
1357     error('Selected Control-Flow Integrity but LTO is disabled')
1358   endif
1359   if config_host.has_key('CONFIG_MODULES')
1360     error('Selected Control-Flow Integrity is not compatible with modules')
1361   endif
1362   # Check for cfi flags. CFI requires LTO so we can't use
1363   # get_supported_arguments, but need a more complex "compiles" which allows
1364   # custom arguments
1365   if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall',
1366                  args: ['-flto', '-fsanitize=cfi-icall'] )
1367     cfi_flags += '-fsanitize=cfi-icall'
1368   else
1369     error('-fsanitize=cfi-icall is not supported by the compiler')
1370   endif
1371   if cc.compiles('int main () { return 0; }',
1372                  name: '-fsanitize-cfi-icall-generalize-pointers',
1373                  args: ['-flto', '-fsanitize=cfi-icall',
1374                         '-fsanitize-cfi-icall-generalize-pointers'] )
1375     cfi_flags += '-fsanitize-cfi-icall-generalize-pointers'
1376   else
1377     error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler')
1378   endif
1379   if get_option('cfi_debug')
1380     if cc.compiles('int main () { return 0; }',
1381                    name: '-fno-sanitize-trap=cfi-icall',
1382                    args: ['-flto', '-fsanitize=cfi-icall',
1383                           '-fno-sanitize-trap=cfi-icall'] )
1384       cfi_flags += '-fno-sanitize-trap=cfi-icall'
1385     else
1386       error('-fno-sanitize-trap=cfi-icall is not supported by the compiler')
1387     endif
1388   endif
1389   add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1390   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
1391 endif
1393 have_host_block_device = (targetos != 'darwin' or
1394     cc.has_header('IOKit/storage/IOMedia.h'))
1396 have_virtfs = (targetos == 'linux' and
1397     have_system and
1398     libattr.found() and
1399     libcap_ng.found())
1401 have_virtfs_proxy_helper = have_virtfs and have_tools
1403 if get_option('virtfs').enabled()
1404   if not have_virtfs
1405     if targetos != 'linux'
1406       error('virtio-9p (virtfs) requires Linux')
1407     elif not libcap_ng.found() or not libattr.found()
1408       error('virtio-9p (virtfs) requires libcap-ng-devel and libattr-devel')
1409     elif not have_system
1410       error('virtio-9p (virtfs) needs system emulation support')
1411     endif
1412   endif
1413 elif get_option('virtfs').disabled()
1414   have_virtfs = false
1415 endif
1417 foreach k : get_option('trace_backends')
1418   config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1419 endforeach
1420 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1422 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1423 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1424 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1425 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1426 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1427 config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath'))
1428 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1429 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1430 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1431 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1432 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1433 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1435 config_host_data.set('CONFIG_ATTR', libattr.found())
1436 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1437 config_host_data.set('CONFIG_COCOA', cocoa.found())
1438 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1439 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1440 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1441 config_host_data.set('CONFIG_LZO', lzo.found())
1442 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1443 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1444 config_host_data.set('CONFIG_CURL', curl.found())
1445 config_host_data.set('CONFIG_CURSES', curses.found())
1446 config_host_data.set('CONFIG_GBM', gbm.found())
1447 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1448 if glusterfs.found()
1449   config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1450   config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1451   config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1452   config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1453   config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1454   config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1455 endif
1456 config_host_data.set('CONFIG_GTK', gtk.found())
1457 config_host_data.set('CONFIG_VTE', vte.found())
1458 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1459 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1460 config_host_data.set('CONFIG_EBPF', libbpf.found())
1461 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1462 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1463 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1464 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1465 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1466 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1467 config_host_data.set('CONFIG_RBD', rbd.found())
1468 config_host_data.set('CONFIG_SDL', sdl.found())
1469 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1470 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1471 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1472 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1473 config_host_data.set('CONFIG_VDE', vde.found())
1474 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1475 config_host_data.set('CONFIG_VNC', vnc.found())
1476 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1477 config_host_data.set('CONFIG_VNC_PNG', png.found())
1478 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1479 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1480 config_host_data.set('CONFIG_VTE', vte.found())
1481 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1482 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1483 config_host_data.set('CONFIG_GETTID', has_gettid)
1484 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1485 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1486 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1487 config_host_data.set('CONFIG_NETTLE', nettle.found())
1488 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1489 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1490 config_host_data.set('CONFIG_STATX', has_statx)
1491 config_host_data.set('CONFIG_ZSTD', zstd.found())
1492 config_host_data.set('CONFIG_FUSE', fuse.found())
1493 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1494 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1495 config_host_data.set('CONFIG_SPICE', spice.found())
1496 config_host_data.set('CONFIG_X11', x11.found())
1497 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1498 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1499 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1500 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1501 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1503 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1504 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1505 config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big')
1507 # has_header
1508 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1509 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1510 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1511 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1512 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1513 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1514 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1515 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1516 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1518 # has_function
1519 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1520 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1521 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1522 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1523 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1524 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
1525 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1526 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1527 config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
1528 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1529 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1530 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1531 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1532 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1533 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1534 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1535 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1536 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1537 if rdma.found()
1538   config_host_data.set('HAVE_IBV_ADVISE_MR',
1539                        cc.has_function('ibv_advise_mr',
1540                                        args: config_host['RDMA_LIBS'].split(),
1541                                        prefix: '#include <infiniband/verbs.h>'))
1542 endif
1544 # has_header_symbol
1545 config_host_data.set('CONFIG_BYTESWAP_H',
1546                      cc.has_header_symbol('byteswap.h', 'bswap_32'))
1547 config_host_data.set('CONFIG_EPOLL_CREATE1',
1548                      cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1549 config_host_data.set('CONFIG_HAS_ENVIRON',
1550                      cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix))
1551 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1552                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1553                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1554 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1555                      cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1556 config_host_data.set('CONFIG_FIEMAP',
1557                      cc.has_header('linux/fiemap.h') and
1558                      cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1559 config_host_data.set('CONFIG_GETRANDOM',
1560                      cc.has_function('getrandom') and
1561                      cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1562 config_host_data.set('CONFIG_INOTIFY',
1563                      cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1564 config_host_data.set('CONFIG_INOTIFY1',
1565                      cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1566 config_host_data.set('CONFIG_IOVEC',
1567                      cc.has_header_symbol('sys/uio.h', 'struct iovec'))
1568 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1569                      cc.has_header_symbol('machine/bswap.h', 'bswap32',
1570                                           prefix: '''#include <sys/endian.h>
1571                                                      #include <sys/types.h>'''))
1572 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1573                      cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1574 config_host_data.set('CONFIG_RTNETLINK',
1575                      cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1576 config_host_data.set('CONFIG_SYSMACROS',
1577                      cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1578 config_host_data.set('HAVE_OPTRESET',
1579                      cc.has_header_symbol('getopt.h', 'optreset'))
1580 config_host_data.set('HAVE_UTMPX',
1581                      cc.has_header_symbol('utmpx.h', 'struct utmpx'))
1582 config_host_data.set('HAVE_IPPROTO_MPTCP',
1583                      cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1585 # has_member
1586 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1587                      cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1588                                    prefix: '#include <signal.h>'))
1589 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1590                      cc.has_member('struct stat', 'st_atim',
1591                                    prefix: '#include <sys/stat.h>'))
1593 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1594   #include <sys/eventfd.h>
1595   int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1596 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1597   #include <unistd.h>
1598   int main(void) {
1599   #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1600   return fdatasync(0);
1601   #else
1602   #error Not supported
1603   #endif
1604   }'''))
1605 config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + '''
1606   #include <sys/types.h>
1607   #include <sys/mman.h>
1608   #include <stddef.h>
1609   int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }'''))
1610 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
1611   #include <sys/mman.h>
1612   int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
1613 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
1614   #include <fcntl.h>
1615   #if !defined(AT_EMPTY_PATH)
1616   # error missing definition
1617   #else
1618   int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
1619   #endif'''))
1620 config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + '''
1621   #include <unistd.h>
1622   #include <fcntl.h>
1624   int main(void)
1625   {
1626       int pipefd[2];
1627       return pipe2(pipefd, O_CLOEXEC);
1628   }'''))
1629 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
1630   #include <sys/mman.h>
1631   #include <stddef.h>
1632   int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
1634 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links('''
1635   #include <pthread.h>
1637   static void *f(void *p) { return NULL; }
1638   int main(void)
1639   {
1640     pthread_t thread;
1641     pthread_create(&thread, 0, f, 0);
1642     pthread_setname_np(thread, "QEMU");
1643     return 0;
1644   }''', dependencies: threads))
1645 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links('''
1646   #include <pthread.h>
1648   static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
1649   int main(void)
1650   {
1651     pthread_t thread;
1652     pthread_create(&thread, 0, f, 0);
1653     return 0;
1654   }''', dependencies: threads))
1656 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
1657   #include <sys/signalfd.h>
1658   #include <stddef.h>
1659   int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
1660 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
1661   #include <unistd.h>
1662   #include <fcntl.h>
1663   #include <limits.h>
1665   int main(void)
1666   {
1667     int len, fd = 0;
1668     len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
1669     splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
1670     return 0;
1671   }'''))
1673 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
1674   #include <sys/mman.h>
1675   int main(int argc, char *argv[]) {
1676     return mlockall(MCL_FUTURE);
1677   }'''))
1679 have_netmap = false
1680 if not get_option('netmap').disabled() and have_system
1681   have_netmap = cc.compiles('''
1682     #include <inttypes.h>
1683     #include <net/if.h>
1684     #include <net/netmap.h>
1685     #include <net/netmap_user.h>
1686     #if (NETMAP_API < 11) || (NETMAP_API > 15)
1687     #error
1688     #endif
1689     int main(void) { return 0; }''')
1690   if not have_netmap and get_option('netmap').enabled()
1691     error('Netmap headers not available')
1692   endif
1693 endif
1694 config_host_data.set('CONFIG_NETMAP', have_netmap)
1696 # Work around a system header bug with some kernel/XFS header
1697 # versions where they both try to define 'struct fsxattr':
1698 # xfs headers will not try to redefine structs from linux headers
1699 # if this macro is set.
1700 config_host_data.set('HAVE_FSXATTR', cc.links('''
1701   #include <linux/fs.h>'
1702   struct fsxattr foo;
1703   int main(void) {
1704     return 0;
1705   }'''))
1707 # Some versions of Mac OS X incorrectly define SIZE_MAX
1708 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
1709     #include <stdint.h>
1710     #include <stdio.h>
1711     int main(int argc, char *argv[]) {
1712         return printf("%zu", SIZE_MAX);
1713     }''', args: ['-Werror']))
1715 # See if 64-bit atomic operations are supported.
1716 # Note that without __atomic builtins, we can only
1717 # assume atomic loads/stores max at pointer size.
1718 config_host_data.set('CONFIG_ATOMIC64', cc.links('''
1719   #include <stdint.h>
1720   int main(void)
1721   {
1722     uint64_t x = 0, y = 0;
1723     y = __atomic_load_n(&x, __ATOMIC_RELAXED);
1724     __atomic_store_n(&x, y, __ATOMIC_RELAXED);
1725     __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
1726     __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
1727     __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
1728     return 0;
1729   }'''))
1731 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
1732   #include <sys/auxv.h>
1733   int main(void) {
1734     return getauxval(AT_HWCAP) == 0;
1735   }'''))
1737 config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + '''
1738   #include <errno.h>
1739   #include <sys/types.h>
1740   #include <sys/socket.h>
1741   #if !defined(AF_VSOCK)
1742   # error missing AF_VSOCK flag
1743   #endif
1744   #include <linux/vm_sockets.h>
1745   int main(void) {
1746     int sock, ret;
1747     struct sockaddr_vm svm;
1748     socklen_t len = sizeof(svm);
1749     sock = socket(AF_VSOCK, SOCK_STREAM, 0);
1750     ret = getpeername(sock, (struct sockaddr *)&svm, &len);
1751     if ((ret == -1) && (errno == ENOTCONN)) {
1752         return 0;
1753     }
1754     return -1;
1755   }'''))
1757 ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target
1758     'HAVE_GDB_BIN']
1759 arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST']
1760 strings = ['CONFIG_IASL']
1761 foreach k, v: config_host
1762   if ignored.contains(k)
1763     # do nothing
1764   elif arrays.contains(k)
1765     if v != ''
1766       v = '"' + '", "'.join(v.split()) + '", '
1767     endif
1768     config_host_data.set(k, v)
1769   elif k == 'ARCH'
1770     config_host_data.set('HOST_' + v.to_upper(), 1)
1771   elif strings.contains(k)
1772     config_host_data.set_quoted(k, v)
1773   elif k.startswith('CONFIG_')
1774     config_host_data.set(k, v == 'y' ? 1 : v)
1775   endif
1776 endforeach
1778 ########################
1779 # Target configuration #
1780 ########################
1782 minikconf = find_program('scripts/minikconf.py')
1783 config_all = {}
1784 config_all_devices = {}
1785 config_all_disas = {}
1786 config_devices_mak_list = []
1787 config_devices_h = {}
1788 config_target_h = {}
1789 config_target_mak = {}
1791 disassemblers = {
1792   'alpha' : ['CONFIG_ALPHA_DIS'],
1793   'arm' : ['CONFIG_ARM_DIS'],
1794   'avr' : ['CONFIG_AVR_DIS'],
1795   'cris' : ['CONFIG_CRIS_DIS'],
1796   'hexagon' : ['CONFIG_HEXAGON_DIS'],
1797   'hppa' : ['CONFIG_HPPA_DIS'],
1798   'i386' : ['CONFIG_I386_DIS'],
1799   'x86_64' : ['CONFIG_I386_DIS'],
1800   'x32' : ['CONFIG_I386_DIS'],
1801   'm68k' : ['CONFIG_M68K_DIS'],
1802   'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
1803   'mips' : ['CONFIG_MIPS_DIS'],
1804   'nios2' : ['CONFIG_NIOS2_DIS'],
1805   'or1k' : ['CONFIG_OPENRISC_DIS'],
1806   'ppc' : ['CONFIG_PPC_DIS'],
1807   'riscv' : ['CONFIG_RISCV_DIS'],
1808   'rx' : ['CONFIG_RX_DIS'],
1809   's390' : ['CONFIG_S390_DIS'],
1810   'sh4' : ['CONFIG_SH4_DIS'],
1811   'sparc' : ['CONFIG_SPARC_DIS'],
1812   'xtensa' : ['CONFIG_XTENSA_DIS'],
1814 if link_language == 'cpp'
1815   disassemblers += {
1816     'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
1817     'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
1818     'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
1819   }
1820 endif
1822 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
1823 host_kconfig = \
1824   (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
1825   ('CONFIG_TPM' in config_host ? ['CONFIG_TPM=y'] : []) + \
1826   (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
1827   (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
1828   ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \
1829   (x11.found() ? ['CONFIG_X11=y'] : []) + \
1830   ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \
1831   ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \
1832   ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
1833   (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
1834   ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
1835   ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \
1836   (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : [])
1838 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
1840 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
1841 actual_target_dirs = []
1842 fdt_required = []
1843 foreach target : target_dirs
1844   config_target = { 'TARGET_NAME': target.split('-')[0] }
1845   if target.endswith('linux-user')
1846     if targetos != 'linux'
1847       if default_targets
1848         continue
1849       endif
1850       error('Target @0@ is only available on a Linux host'.format(target))
1851     endif
1852     config_target += { 'CONFIG_LINUX_USER': 'y' }
1853   elif target.endswith('bsd-user')
1854     if 'CONFIG_BSD' not in config_host
1855       if default_targets
1856         continue
1857       endif
1858       error('Target @0@ is only available on a BSD host'.format(target))
1859     endif
1860     config_target += { 'CONFIG_BSD_USER': 'y' }
1861   elif target.endswith('softmmu')
1862     config_target += { 'CONFIG_SOFTMMU': 'y' }
1863   endif
1864   if target.endswith('-user')
1865     config_target += {
1866       'CONFIG_USER_ONLY': 'y',
1867       'CONFIG_QEMU_INTERP_PREFIX':
1868         config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME'])
1869     }
1870   endif
1872   accel_kconfig = []
1873   foreach sym: accelerators
1874     if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
1875       config_target += { sym: 'y' }
1876       config_all += { sym: 'y' }
1877       if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
1878         config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
1879       elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough
1880         config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' }
1881       endif
1882       if target in modular_tcg
1883         config_target += { 'CONFIG_TCG_MODULAR': 'y' }
1884       else
1885         config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
1886       endif
1887       accel_kconfig += [ sym + '=y' ]
1888     endif
1889   endforeach
1890   if accel_kconfig.length() == 0
1891     if default_targets
1892       continue
1893     endif
1894     error('No accelerator available for target @0@'.format(target))
1895   endif
1897   actual_target_dirs += target
1898   config_target += keyval.load('configs/targets' / target + '.mak')
1899   config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
1901   if 'TARGET_NEED_FDT' in config_target
1902     fdt_required += target
1903   endif
1905   # Add default keys
1906   if 'TARGET_BASE_ARCH' not in config_target
1907     config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
1908   endif
1909   if 'TARGET_ABI_DIR' not in config_target
1910     config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
1911   endif
1913   foreach k, v: disassemblers
1914     if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
1915       foreach sym: v
1916         config_target += { sym: 'y' }
1917         config_all_disas += { sym: 'y' }
1918       endforeach
1919     endif
1920   endforeach
1922   config_target_data = configuration_data()
1923   foreach k, v: config_target
1924     if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
1925       # do nothing
1926     elif ignored.contains(k)
1927       # do nothing
1928     elif k == 'TARGET_BASE_ARCH'
1929       # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
1930       # not used to select files from sourcesets.
1931       config_target_data.set('TARGET_' + v.to_upper(), 1)
1932     elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
1933       config_target_data.set_quoted(k, v)
1934     elif v == 'y'
1935       config_target_data.set(k, 1)
1936     else
1937       config_target_data.set(k, v)
1938     endif
1939   endforeach
1940   config_target_data.set('QEMU_ARCH',
1941                          'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
1942   config_target_h += {target: configure_file(output: target + '-config-target.h',
1943                                                configuration: config_target_data)}
1945   if target.endswith('-softmmu')
1946     config_input = meson.get_external_property(target, 'default')
1947     config_devices_mak = target + '-config-devices.mak'
1948     config_devices_mak = configure_file(
1949       input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
1950       output: config_devices_mak,
1951       depfile: config_devices_mak + '.d',
1952       capture: true,
1953       command: [minikconf,
1954                 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
1955                 config_devices_mak, '@DEPFILE@', '@INPUT@',
1956                 host_kconfig, accel_kconfig,
1957                 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
1959     config_devices_data = configuration_data()
1960     config_devices = keyval.load(config_devices_mak)
1961     foreach k, v: config_devices
1962       config_devices_data.set(k, 1)
1963     endforeach
1964     config_devices_mak_list += config_devices_mak
1965     config_devices_h += {target: configure_file(output: target + '-config-devices.h',
1966                                                 configuration: config_devices_data)}
1967     config_target += config_devices
1968     config_all_devices += config_devices
1969   endif
1970   config_target_mak += {target: config_target}
1971 endforeach
1972 target_dirs = actual_target_dirs
1974 # This configuration is used to build files that are shared by
1975 # multiple binaries, and then extracted out of the "common"
1976 # static_library target.
1978 # We do not use all_sources()/all_dependencies(), because it would
1979 # build literally all source files, including devices only used by
1980 # targets that are not built for this compilation.  The CONFIG_ALL
1981 # pseudo symbol replaces it.
1983 config_all += config_all_devices
1984 config_all += config_host
1985 config_all += config_all_disas
1986 config_all += {
1987   'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'),
1988   'CONFIG_SOFTMMU': have_system,
1989   'CONFIG_USER_ONLY': have_user,
1990   'CONFIG_ALL': true,
1993 ##############
1994 # Submodules #
1995 ##############
1997 capstone = not_found
1998 capstone_opt = get_option('capstone')
1999 if capstone_opt in ['enabled', 'auto', 'system']
2000   have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
2001   capstone = dependency('capstone', version: '>=4.0',
2002                         kwargs: static_kwargs, method: 'pkg-config',
2003                         required: capstone_opt == 'system' or
2004                                   capstone_opt == 'enabled' and not have_internal)
2006   # Some versions of capstone have broken pkg-config file
2007   # that reports a wrong -I path, causing the #include to
2008   # fail later. If the system has such a broken version
2009   # do not use it.
2010   if capstone.found() and not cc.compiles('#include <capstone.h>',
2011                                           dependencies: [capstone])
2012     capstone = not_found
2013     if capstone_opt == 'system'
2014       error('system capstone requested, it does not appear to work')
2015     endif
2016   endif
2018   if capstone.found()
2019     capstone_opt = 'system'
2020   elif have_internal
2021     capstone_opt = 'internal'
2022   else
2023     capstone_opt = 'disabled'
2024   endif
2025 endif
2026 if capstone_opt == 'internal'
2027   capstone_data = configuration_data()
2028   capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
2030   capstone_files = files(
2031     'capstone/cs.c',
2032     'capstone/MCInst.c',
2033     'capstone/MCInstrDesc.c',
2034     'capstone/MCRegisterInfo.c',
2035     'capstone/SStream.c',
2036     'capstone/utils.c'
2037   )
2039   if 'CONFIG_ARM_DIS' in config_all_disas
2040     capstone_data.set('CAPSTONE_HAS_ARM', '1')
2041     capstone_files += files(
2042       'capstone/arch/ARM/ARMDisassembler.c',
2043       'capstone/arch/ARM/ARMInstPrinter.c',
2044       'capstone/arch/ARM/ARMMapping.c',
2045       'capstone/arch/ARM/ARMModule.c'
2046     )
2047   endif
2049   # FIXME: This config entry currently depends on a c++ compiler.
2050   # Which is needed for building libvixl, but not for capstone.
2051   if 'CONFIG_ARM_A64_DIS' in config_all_disas
2052     capstone_data.set('CAPSTONE_HAS_ARM64', '1')
2053     capstone_files += files(
2054       'capstone/arch/AArch64/AArch64BaseInfo.c',
2055       'capstone/arch/AArch64/AArch64Disassembler.c',
2056       'capstone/arch/AArch64/AArch64InstPrinter.c',
2057       'capstone/arch/AArch64/AArch64Mapping.c',
2058       'capstone/arch/AArch64/AArch64Module.c'
2059     )
2060   endif
2062   if 'CONFIG_PPC_DIS' in config_all_disas
2063     capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
2064     capstone_files += files(
2065       'capstone/arch/PowerPC/PPCDisassembler.c',
2066       'capstone/arch/PowerPC/PPCInstPrinter.c',
2067       'capstone/arch/PowerPC/PPCMapping.c',
2068       'capstone/arch/PowerPC/PPCModule.c'
2069     )
2070   endif
2072   if 'CONFIG_S390_DIS' in config_all_disas
2073     capstone_data.set('CAPSTONE_HAS_SYSZ', '1')
2074     capstone_files += files(
2075       'capstone/arch/SystemZ/SystemZDisassembler.c',
2076       'capstone/arch/SystemZ/SystemZInstPrinter.c',
2077       'capstone/arch/SystemZ/SystemZMapping.c',
2078       'capstone/arch/SystemZ/SystemZModule.c',
2079       'capstone/arch/SystemZ/SystemZMCTargetDesc.c'
2080     )
2081   endif
2083   if 'CONFIG_I386_DIS' in config_all_disas
2084     capstone_data.set('CAPSTONE_HAS_X86', 1)
2085     capstone_files += files(
2086       'capstone/arch/X86/X86Disassembler.c',
2087       'capstone/arch/X86/X86DisassemblerDecoder.c',
2088       'capstone/arch/X86/X86ATTInstPrinter.c',
2089       'capstone/arch/X86/X86IntelInstPrinter.c',
2090       'capstone/arch/X86/X86InstPrinterCommon.c',
2091       'capstone/arch/X86/X86Mapping.c',
2092       'capstone/arch/X86/X86Module.c'
2093     )
2094   endif
2096   configure_file(output: 'capstone-defs.h', configuration: capstone_data)
2098   capstone_cargs = [
2099     # FIXME: There does not seem to be a way to completely replace the c_args
2100     # that come from add_project_arguments() -- we can only add to them.
2101     # So: disable all warnings with a big hammer.
2102     '-Wno-error', '-w',
2104     # Include all configuration defines via a header file, which will wind up
2105     # as a dependency on the object file, and thus changes here will result
2106     # in a rebuild.
2107     '-include', 'capstone-defs.h'
2108   ]
2110   libcapstone = static_library('capstone',
2111                                build_by_default: false,
2112                                sources: capstone_files,
2113                                c_args: capstone_cargs,
2114                                include_directories: 'capstone/include')
2115   capstone = declare_dependency(link_with: libcapstone,
2116                                 include_directories: 'capstone/include/capstone')
2117 endif
2119 slirp = not_found
2120 slirp_opt = 'disabled'
2121 if have_system
2122   slirp_opt = get_option('slirp')
2123   if slirp_opt in ['enabled', 'auto', 'system']
2124     have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2125     slirp = dependency('slirp', kwargs: static_kwargs,
2126                        method: 'pkg-config',
2127                        required: slirp_opt == 'system' or
2128                                  slirp_opt == 'enabled' and not have_internal)
2129     if slirp.found()
2130       slirp_opt = 'system'
2131     elif have_internal
2132       slirp_opt = 'internal'
2133     else
2134       slirp_opt = 'disabled'
2135     endif
2136   endif
2137   if slirp_opt == 'internal'
2138     slirp_deps = []
2139     if targetos == 'windows'
2140       slirp_deps = cc.find_library('iphlpapi')
2141     elif targetos == 'darwin'
2142       slirp_deps = cc.find_library('resolv')
2143     endif
2144     slirp_conf = configuration_data()
2145     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2146     slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2147     slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2148     slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2149     slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2150     slirp_files = [
2151       'slirp/src/arp_table.c',
2152       'slirp/src/bootp.c',
2153       'slirp/src/cksum.c',
2154       'slirp/src/dhcpv6.c',
2155       'slirp/src/dnssearch.c',
2156       'slirp/src/if.c',
2157       'slirp/src/ip6_icmp.c',
2158       'slirp/src/ip6_input.c',
2159       'slirp/src/ip6_output.c',
2160       'slirp/src/ip_icmp.c',
2161       'slirp/src/ip_input.c',
2162       'slirp/src/ip_output.c',
2163       'slirp/src/mbuf.c',
2164       'slirp/src/misc.c',
2165       'slirp/src/ncsi.c',
2166       'slirp/src/ndp_table.c',
2167       'slirp/src/sbuf.c',
2168       'slirp/src/slirp.c',
2169       'slirp/src/socket.c',
2170       'slirp/src/state.c',
2171       'slirp/src/stream.c',
2172       'slirp/src/tcp_input.c',
2173       'slirp/src/tcp_output.c',
2174       'slirp/src/tcp_subr.c',
2175       'slirp/src/tcp_timer.c',
2176       'slirp/src/tftp.c',
2177       'slirp/src/udp.c',
2178       'slirp/src/udp6.c',
2179       'slirp/src/util.c',
2180       'slirp/src/version.c',
2181       'slirp/src/vmstate.c',
2182     ]
2184     configure_file(
2185       input : 'slirp/src/libslirp-version.h.in',
2186       output : 'libslirp-version.h',
2187       configuration: slirp_conf)
2189     slirp_inc = include_directories('slirp', 'slirp/src')
2190     libslirp = static_library('slirp',
2191                               build_by_default: false,
2192                               sources: slirp_files,
2193                               c_args: slirp_cargs,
2194                               include_directories: slirp_inc)
2195     slirp = declare_dependency(link_with: libslirp,
2196                                dependencies: slirp_deps,
2197                                include_directories: slirp_inc)
2198   endif
2199 endif
2201 # For CFI, we need to compile slirp as a static library together with qemu.
2202 # This is because we register slirp functions as callbacks for QEMU Timers.
2203 # When using a system-wide shared libslirp, the type information for the
2204 # callback is missing and the timer call produces a false positive with CFI.
2206 # Now that slirp_opt has been defined, check if the selected slirp is compatible
2207 # with control-flow integrity.
2208 if get_option('cfi') and slirp_opt == 'system'
2209   error('Control-Flow Integrity is not compatible with system-wide slirp.' \
2210          + ' Please configure with --enable-slirp=git')
2211 endif
2213 fdt = not_found
2214 fdt_opt = get_option('fdt')
2215 if have_system
2216   if fdt_opt in ['enabled', 'auto', 'system']
2217     have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2218     fdt = cc.find_library('fdt', kwargs: static_kwargs,
2219                           required: fdt_opt == 'system' or
2220                                     fdt_opt == 'enabled' and not have_internal)
2221     if fdt.found() and cc.links('''
2222        #include <libfdt.h>
2223        #include <libfdt_env.h>
2224        int main(void) { fdt_check_full(NULL, 0); return 0; }''',
2225          dependencies: fdt)
2226       fdt_opt = 'system'
2227     elif fdt_opt == 'system'
2228        error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2229     elif have_internal
2230       fdt_opt = 'internal'
2231     else
2232       fdt_opt = 'disabled'
2233       fdt = not_found
2234     endif
2235   endif
2236   if fdt_opt == 'internal'
2237     fdt_files = files(
2238       'dtc/libfdt/fdt.c',
2239       'dtc/libfdt/fdt_ro.c',
2240       'dtc/libfdt/fdt_wip.c',
2241       'dtc/libfdt/fdt_sw.c',
2242       'dtc/libfdt/fdt_rw.c',
2243       'dtc/libfdt/fdt_strerror.c',
2244       'dtc/libfdt/fdt_empty_tree.c',
2245       'dtc/libfdt/fdt_addresses.c',
2246       'dtc/libfdt/fdt_overlay.c',
2247       'dtc/libfdt/fdt_check.c',
2248     )
2250     fdt_inc = include_directories('dtc/libfdt')
2251     libfdt = static_library('fdt',
2252                             build_by_default: false,
2253                             sources: fdt_files,
2254                             include_directories: fdt_inc)
2255     fdt = declare_dependency(link_with: libfdt,
2256                              include_directories: fdt_inc)
2257   endif
2258 endif
2259 if not fdt.found() and fdt_required.length() > 0
2260   error('fdt not available but required by targets ' + ', '.join(fdt_required))
2261 endif
2263 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2264 config_host_data.set('CONFIG_FDT', fdt.found())
2265 config_host_data.set('CONFIG_SLIRP', slirp.found())
2267 #####################
2268 # Generated sources #
2269 #####################
2271 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2273 hxtool = find_program('scripts/hxtool')
2274 shaderinclude = find_program('scripts/shaderinclude.pl')
2275 qapi_gen = find_program('scripts/qapi-gen.py')
2276 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2277                      meson.current_source_dir() / 'scripts/qapi/commands.py',
2278                      meson.current_source_dir() / 'scripts/qapi/common.py',
2279                      meson.current_source_dir() / 'scripts/qapi/error.py',
2280                      meson.current_source_dir() / 'scripts/qapi/events.py',
2281                      meson.current_source_dir() / 'scripts/qapi/expr.py',
2282                      meson.current_source_dir() / 'scripts/qapi/gen.py',
2283                      meson.current_source_dir() / 'scripts/qapi/introspect.py',
2284                      meson.current_source_dir() / 'scripts/qapi/parser.py',
2285                      meson.current_source_dir() / 'scripts/qapi/schema.py',
2286                      meson.current_source_dir() / 'scripts/qapi/source.py',
2287                      meson.current_source_dir() / 'scripts/qapi/types.py',
2288                      meson.current_source_dir() / 'scripts/qapi/visit.py',
2289                      meson.current_source_dir() / 'scripts/qapi/common.py',
2290                      meson.current_source_dir() / 'scripts/qapi-gen.py'
2293 tracetool = [
2294   python, files('scripts/tracetool.py'),
2295    '--backend=' + ','.join(get_option('trace_backends'))
2297 tracetool_depends = files(
2298   'scripts/tracetool/backend/log.py',
2299   'scripts/tracetool/backend/__init__.py',
2300   'scripts/tracetool/backend/dtrace.py',
2301   'scripts/tracetool/backend/ftrace.py',
2302   'scripts/tracetool/backend/simple.py',
2303   'scripts/tracetool/backend/syslog.py',
2304   'scripts/tracetool/backend/ust.py',
2305   'scripts/tracetool/format/tcg_h.py',
2306   'scripts/tracetool/format/ust_events_c.py',
2307   'scripts/tracetool/format/ust_events_h.py',
2308   'scripts/tracetool/format/__init__.py',
2309   'scripts/tracetool/format/d.py',
2310   'scripts/tracetool/format/tcg_helper_c.py',
2311   'scripts/tracetool/format/simpletrace_stap.py',
2312   'scripts/tracetool/format/c.py',
2313   'scripts/tracetool/format/h.py',
2314   'scripts/tracetool/format/tcg_helper_h.py',
2315   'scripts/tracetool/format/log_stap.py',
2316   'scripts/tracetool/format/stap.py',
2317   'scripts/tracetool/format/tcg_helper_wrapper_h.py',
2318   'scripts/tracetool/__init__.py',
2319   'scripts/tracetool/transform.py',
2320   'scripts/tracetool/vcpu.py'
2323 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2324                     meson.current_source_dir(),
2325                     config_host['PKGVERSION'], meson.project_version()]
2326 qemu_version = custom_target('qemu-version.h',
2327                              output: 'qemu-version.h',
2328                              command: qemu_version_cmd,
2329                              capture: true,
2330                              build_by_default: true,
2331                              build_always_stale: true)
2332 genh += qemu_version
2334 hxdep = []
2335 hx_headers = [
2336   ['qemu-options.hx', 'qemu-options.def'],
2337   ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2339 if have_system
2340   hx_headers += [
2341     ['hmp-commands.hx', 'hmp-commands.h'],
2342     ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2343   ]
2344 endif
2345 foreach d : hx_headers
2346   hxdep += custom_target(d[1],
2347                 input: files(d[0]),
2348                 output: d[1],
2349                 capture: true,
2350                 build_by_default: true, # to be removed when added to a target
2351                 command: [hxtool, '-h', '@INPUT0@'])
2352 endforeach
2353 genh += hxdep
2355 ###################
2356 # Collect sources #
2357 ###################
2359 authz_ss = ss.source_set()
2360 blockdev_ss = ss.source_set()
2361 block_ss = ss.source_set()
2362 bsd_user_ss = ss.source_set()
2363 chardev_ss = ss.source_set()
2364 common_ss = ss.source_set()
2365 crypto_ss = ss.source_set()
2366 io_ss = ss.source_set()
2367 linux_user_ss = ss.source_set()
2368 qmp_ss = ss.source_set()
2369 qom_ss = ss.source_set()
2370 softmmu_ss = ss.source_set()
2371 specific_fuzz_ss = ss.source_set()
2372 specific_ss = ss.source_set()
2373 stub_ss = ss.source_set()
2374 trace_ss = ss.source_set()
2375 user_ss = ss.source_set()
2376 util_ss = ss.source_set()
2378 # accel modules
2379 qtest_module_ss = ss.source_set()
2380 tcg_module_ss = ss.source_set()
2382 modules = {}
2383 target_modules = {}
2384 hw_arch = {}
2385 target_arch = {}
2386 target_softmmu_arch = {}
2387 target_user_arch = {}
2389 ###############
2390 # Trace files #
2391 ###############
2393 # TODO: add each directory to the subdirs from its own meson.build, once
2394 # we have those
2395 trace_events_subdirs = [
2396   'crypto',
2397   'qapi',
2398   'qom',
2399   'monitor',
2400   'util',
2402 if have_user
2403   trace_events_subdirs += [ 'linux-user' ]
2404 endif
2405 if have_block
2406   trace_events_subdirs += [
2407     'authz',
2408     'block',
2409     'io',
2410     'nbd',
2411     'scsi',
2412   ]
2413 endif
2414 if have_system
2415   trace_events_subdirs += [
2416     'accel/kvm',
2417     'audio',
2418     'backends',
2419     'backends/tpm',
2420     'chardev',
2421     'ebpf',
2422     'hw/9pfs',
2423     'hw/acpi',
2424     'hw/adc',
2425     'hw/alpha',
2426     'hw/arm',
2427     'hw/audio',
2428     'hw/block',
2429     'hw/block/dataplane',
2430     'hw/char',
2431     'hw/display',
2432     'hw/dma',
2433     'hw/hppa',
2434     'hw/hyperv',
2435     'hw/i2c',
2436     'hw/i386',
2437     'hw/i386/xen',
2438     'hw/ide',
2439     'hw/input',
2440     'hw/intc',
2441     'hw/isa',
2442     'hw/mem',
2443     'hw/mips',
2444     'hw/misc',
2445     'hw/misc/macio',
2446     'hw/net',
2447     'hw/net/can',
2448     'hw/nubus',
2449     'hw/nvme',
2450     'hw/nvram',
2451     'hw/pci',
2452     'hw/pci-host',
2453     'hw/ppc',
2454     'hw/rdma',
2455     'hw/rdma/vmw',
2456     'hw/rtc',
2457     'hw/s390x',
2458     'hw/scsi',
2459     'hw/sd',
2460     'hw/sparc',
2461     'hw/sparc64',
2462     'hw/ssi',
2463     'hw/timer',
2464     'hw/tpm',
2465     'hw/usb',
2466     'hw/vfio',
2467     'hw/virtio',
2468     'hw/watchdog',
2469     'hw/xen',
2470     'hw/gpio',
2471     'migration',
2472     'net',
2473     'softmmu',
2474     'ui',
2475     'hw/remote',
2476   ]
2477 endif
2478 if have_system or have_user
2479   trace_events_subdirs += [
2480     'accel/tcg',
2481     'hw/core',
2482     'target/arm',
2483     'target/arm/hvf',
2484     'target/hppa',
2485     'target/i386',
2486     'target/i386/kvm',
2487     'target/mips/tcg',
2488     'target/ppc',
2489     'target/riscv',
2490     'target/s390x',
2491     'target/s390x/kvm',
2492     'target/sparc',
2493   ]
2494 endif
2496 vhost_user = not_found
2497 if 'CONFIG_VHOST_USER' in config_host
2498   libvhost_user = subproject('libvhost-user')
2499   vhost_user = libvhost_user.get_variable('vhost_user_dep')
2500 endif
2502 subdir('qapi')
2503 subdir('qobject')
2504 subdir('stubs')
2505 subdir('trace')
2506 subdir('util')
2507 subdir('qom')
2508 subdir('authz')
2509 subdir('crypto')
2510 subdir('ui')
2513 if enable_modules
2514   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
2515   modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
2516 endif
2518 stub_ss = stub_ss.apply(config_all, strict: false)
2520 util_ss.add_all(trace_ss)
2521 util_ss = util_ss.apply(config_all, strict: false)
2522 libqemuutil = static_library('qemuutil',
2523                              sources: util_ss.sources() + stub_ss.sources() + genh,
2524                              dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
2525 qemuutil = declare_dependency(link_with: libqemuutil,
2526                               sources: genh + version_res)
2528 if have_system or have_user
2529   decodetree = generator(find_program('scripts/decodetree.py'),
2530                          output: 'decode-@BASENAME@.c.inc',
2531                          arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
2532   subdir('libdecnumber')
2533   subdir('target')
2534 endif
2536 subdir('audio')
2537 subdir('io')
2538 subdir('chardev')
2539 subdir('fsdev')
2540 subdir('dump')
2542 if have_block
2543   block_ss.add(files(
2544     'block.c',
2545     'blockjob.c',
2546     'job.c',
2547     'qemu-io-cmds.c',
2548   ))
2549   block_ss.add(when: 'CONFIG_REPLICATION', if_true: files('replication.c'))
2551   subdir('nbd')
2552   subdir('scsi')
2553   subdir('block')
2555   blockdev_ss.add(files(
2556     'blockdev.c',
2557     'blockdev-nbd.c',
2558     'iothread.c',
2559     'job-qmp.c',
2560   ), gnutls)
2562   # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
2563   # os-win32.c does not
2564   blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
2565   softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
2566 endif
2568 common_ss.add(files('cpus-common.c'))
2570 subdir('softmmu')
2572 common_ss.add(capstone)
2573 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
2575 # Work around a gcc bug/misfeature wherein constant propagation looks
2576 # through an alias:
2577 #   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
2578 # to guess that a const variable is always zero.  Without lto, this is
2579 # impossible, as the alias is restricted to page-vary-common.c.  Indeed,
2580 # without lto, not even the alias is required -- we simply use different
2581 # declarations in different compilation units.
2582 pagevary = files('page-vary-common.c')
2583 if get_option('b_lto')
2584   pagevary_flags = ['-fno-lto']
2585   if get_option('cfi')
2586     pagevary_flags += '-fno-sanitize=cfi-icall'
2587   endif
2588   pagevary = static_library('page-vary-common', sources: pagevary,
2589                             c_args: pagevary_flags)
2590   pagevary = declare_dependency(link_with: pagevary)
2591 endif
2592 common_ss.add(pagevary)
2593 specific_ss.add(files('page-vary.c'))
2595 subdir('backends')
2596 subdir('disas')
2597 subdir('migration')
2598 subdir('monitor')
2599 subdir('net')
2600 subdir('replay')
2601 subdir('semihosting')
2602 subdir('hw')
2603 subdir('tcg')
2604 subdir('fpu')
2605 subdir('accel')
2606 subdir('plugins')
2607 subdir('bsd-user')
2608 subdir('linux-user')
2609 subdir('ebpf')
2611 common_ss.add(libbpf)
2613 specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
2615 linux_user_ss.add(files('thunk.c'))
2616 specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
2618 # needed for fuzzing binaries
2619 subdir('tests/qtest/libqos')
2620 subdir('tests/qtest/fuzz')
2622 # accel modules
2623 tcg_real_module_ss = ss.source_set()
2624 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
2625 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
2626 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
2627                                 'tcg': tcg_real_module_ss }}
2629 ########################
2630 # Library dependencies #
2631 ########################
2633 modinfo_collect = find_program('scripts/modinfo-collect.py')
2634 modinfo_generate = find_program('scripts/modinfo-generate.py')
2635 modinfo_files = []
2637 block_mods = []
2638 softmmu_mods = []
2639 foreach d, list : modules
2640   foreach m, module_ss : list
2641     if enable_modules and targetos != 'windows'
2642       module_ss = module_ss.apply(config_all, strict: false)
2643       sl = static_library(d + '-' + m, [genh, module_ss.sources()],
2644                           dependencies: [modulecommon, module_ss.dependencies()], pic: true)
2645       if d == 'block'
2646         block_mods += sl
2647       else
2648         softmmu_mods += sl
2649       endif
2650       if module_ss.sources() != []
2651         # FIXME: Should use sl.extract_all_objects(recursive: true) as
2652         # input. Sources can be used multiple times but objects are
2653         # unique when it comes to lookup in compile_commands.json.
2654         # Depnds on a mesion version with
2655         # https://github.com/mesonbuild/meson/pull/8900
2656         modinfo_files += custom_target(d + '-' + m + '.modinfo',
2657                                        output: d + '-' + m + '.modinfo',
2658                                        input: module_ss.sources() + genh,
2659                                        capture: true,
2660                                        command: [modinfo_collect, module_ss.sources()])
2661       endif
2662     else
2663       if d == 'block'
2664         block_ss.add_all(module_ss)
2665       else
2666         softmmu_ss.add_all(module_ss)
2667       endif
2668     endif
2669   endforeach
2670 endforeach
2672 foreach d, list : target_modules
2673   foreach m, module_ss : list
2674     if enable_modules and targetos != 'windows'
2675       foreach target : target_dirs
2676         if target.endswith('-softmmu')
2677           config_target = config_target_mak[target]
2678           config_target += config_host
2679           target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2680           c_args = ['-DNEED_CPU_H',
2681                     '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2682                     '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2683           target_module_ss = module_ss.apply(config_target, strict: false)
2684           if target_module_ss.sources() != []
2685             module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
2686             sl = static_library(module_name,
2687                                 [genh, target_module_ss.sources()],
2688                                 dependencies: [modulecommon, target_module_ss.dependencies()],
2689                                 include_directories: target_inc,
2690                                 c_args: c_args,
2691                                 pic: true)
2692             softmmu_mods += sl
2693             # FIXME: Should use sl.extract_all_objects(recursive: true) too.
2694             modinfo_files += custom_target(module_name + '.modinfo',
2695                                            output: module_name + '.modinfo',
2696                                            input: target_module_ss.sources() + genh,
2697                                            capture: true,
2698                                            command: [modinfo_collect, '--target', target, target_module_ss.sources()])
2699           endif
2700         endif
2701       endforeach
2702     else
2703       specific_ss.add_all(module_ss)
2704     endif
2705   endforeach
2706 endforeach
2708 if enable_modules
2709   modinfo_src = custom_target('modinfo.c',
2710                               output: 'modinfo.c',
2711                               input: modinfo_files,
2712                               command: [modinfo_generate, '@INPUT@'],
2713                               capture: true)
2714   modinfo_lib = static_library('modinfo', modinfo_src)
2715   modinfo_dep = declare_dependency(link_whole: modinfo_lib)
2716   softmmu_ss.add(modinfo_dep)
2717 endif
2719 nm = find_program('nm')
2720 undefsym = find_program('scripts/undefsym.py')
2721 block_syms = custom_target('block.syms', output: 'block.syms',
2722                              input: [libqemuutil, block_mods],
2723                              capture: true,
2724                              command: [undefsym, nm, '@INPUT@'])
2725 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
2726                              input: [libqemuutil, softmmu_mods],
2727                              capture: true,
2728                              command: [undefsym, nm, '@INPUT@'])
2730 qom_ss = qom_ss.apply(config_host, strict: false)
2731 libqom = static_library('qom', qom_ss.sources() + genh,
2732                         dependencies: [qom_ss.dependencies()],
2733                         name_suffix: 'fa')
2735 qom = declare_dependency(link_whole: libqom)
2737 authz_ss = authz_ss.apply(config_host, strict: false)
2738 libauthz = static_library('authz', authz_ss.sources() + genh,
2739                           dependencies: [authz_ss.dependencies()],
2740                           name_suffix: 'fa',
2741                           build_by_default: false)
2743 authz = declare_dependency(link_whole: libauthz,
2744                            dependencies: qom)
2746 crypto_ss = crypto_ss.apply(config_host, strict: false)
2747 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
2748                            dependencies: [crypto_ss.dependencies()],
2749                            name_suffix: 'fa',
2750                            build_by_default: false)
2752 crypto = declare_dependency(link_whole: libcrypto,
2753                             dependencies: [authz, qom])
2755 io_ss = io_ss.apply(config_host, strict: false)
2756 libio = static_library('io', io_ss.sources() + genh,
2757                        dependencies: [io_ss.dependencies()],
2758                        link_with: libqemuutil,
2759                        name_suffix: 'fa',
2760                        build_by_default: false)
2762 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
2764 libmigration = static_library('migration', sources: migration_files + genh,
2765                               name_suffix: 'fa',
2766                               build_by_default: false)
2767 migration = declare_dependency(link_with: libmigration,
2768                                dependencies: [zlib, qom, io])
2769 softmmu_ss.add(migration)
2771 block_ss = block_ss.apply(config_host, strict: false)
2772 libblock = static_library('block', block_ss.sources() + genh,
2773                           dependencies: block_ss.dependencies(),
2774                           link_depends: block_syms,
2775                           name_suffix: 'fa',
2776                           build_by_default: false)
2778 block = declare_dependency(link_whole: [libblock],
2779                            link_args: '@block.syms',
2780                            dependencies: [crypto, io])
2782 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
2783 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
2784                              dependencies: blockdev_ss.dependencies(),
2785                              name_suffix: 'fa',
2786                              build_by_default: false)
2788 blockdev = declare_dependency(link_whole: [libblockdev],
2789                               dependencies: [block])
2791 qmp_ss = qmp_ss.apply(config_host, strict: false)
2792 libqmp = static_library('qmp', qmp_ss.sources() + genh,
2793                         dependencies: qmp_ss.dependencies(),
2794                         name_suffix: 'fa',
2795                         build_by_default: false)
2797 qmp = declare_dependency(link_whole: [libqmp])
2799 libchardev = static_library('chardev', chardev_ss.sources() + genh,
2800                             name_suffix: 'fa',
2801                             dependencies: [gnutls],
2802                             build_by_default: false)
2804 chardev = declare_dependency(link_whole: libchardev)
2806 libhwcore = static_library('hwcore', sources: hwcore_files + genh,
2807                            name_suffix: 'fa',
2808                            build_by_default: false)
2809 hwcore = declare_dependency(link_whole: libhwcore)
2810 common_ss.add(hwcore)
2812 ###########
2813 # Targets #
2814 ###########
2816 foreach m : block_mods + softmmu_mods
2817   shared_module(m.name(),
2818                 name_prefix: '',
2819                 link_whole: m,
2820                 install: true,
2821                 install_dir: qemu_moddir)
2822 endforeach
2824 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
2825 common_ss.add(qom, qemuutil)
2827 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
2828 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
2830 common_all = common_ss.apply(config_all, strict: false)
2831 common_all = static_library('common',
2832                             build_by_default: false,
2833                             sources: common_all.sources() + genh,
2834                             implicit_include_directories: false,
2835                             dependencies: common_all.dependencies(),
2836                             name_suffix: 'fa')
2838 feature_to_c = find_program('scripts/feature_to_c.sh')
2840 emulators = {}
2841 foreach target : target_dirs
2842   config_target = config_target_mak[target]
2843   target_name = config_target['TARGET_NAME']
2844   arch = config_target['TARGET_BASE_ARCH']
2845   arch_srcs = [config_target_h[target]]
2846   arch_deps = []
2847   c_args = ['-DNEED_CPU_H',
2848             '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
2849             '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
2850   link_args = emulator_link_args
2852   config_target += config_host
2853   target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
2854   if targetos == 'linux'
2855     target_inc += include_directories('linux-headers', is_system: true)
2856   endif
2857   if target.endswith('-softmmu')
2858     qemu_target_name = 'qemu-system-' + target_name
2859     target_type='system'
2860     t = target_softmmu_arch[arch].apply(config_target, strict: false)
2861     arch_srcs += t.sources()
2862     arch_deps += t.dependencies()
2864     hw_dir = target_name == 'sparc64' ? 'sparc64' : arch
2865     hw = hw_arch[hw_dir].apply(config_target, strict: false)
2866     arch_srcs += hw.sources()
2867     arch_deps += hw.dependencies()
2869     arch_srcs += config_devices_h[target]
2870     link_args += ['@block.syms', '@qemu.syms']
2871   else
2872     abi = config_target['TARGET_ABI_DIR']
2873     target_type='user'
2874     qemu_target_name = 'qemu-' + target_name
2875     if arch in target_user_arch
2876       t = target_user_arch[arch].apply(config_target, strict: false)
2877       arch_srcs += t.sources()
2878       arch_deps += t.dependencies()
2879     endif
2880     if 'CONFIG_LINUX_USER' in config_target
2881       base_dir = 'linux-user'
2882       target_inc += include_directories('linux-user/host/' / config_host['ARCH'])
2883     endif
2884     if 'CONFIG_BSD_USER' in config_target
2885       base_dir = 'bsd-user'
2886       target_inc += include_directories('bsd-user/' / targetos)
2887       dir = base_dir / abi
2888       arch_srcs += files(dir / 'target_arch_cpu.c')
2889     endif
2890     target_inc += include_directories(
2891       base_dir,
2892       base_dir / abi,
2893     )
2894     if 'CONFIG_LINUX_USER' in config_target
2895       dir = base_dir / abi
2896       arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
2897       if config_target.has_key('TARGET_SYSTBL_ABI')
2898         arch_srcs += \
2899           syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
2900                                              extra_args : config_target['TARGET_SYSTBL_ABI'])
2901       endif
2902     endif
2903   endif
2905   if 'TARGET_XML_FILES' in config_target
2906     gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
2907                                 output: target + '-gdbstub-xml.c',
2908                                 input: files(config_target['TARGET_XML_FILES'].split()),
2909                                 command: [feature_to_c, '@INPUT@'],
2910                                 capture: true)
2911     arch_srcs += gdbstub_xml
2912   endif
2914   t = target_arch[arch].apply(config_target, strict: false)
2915   arch_srcs += t.sources()
2916   arch_deps += t.dependencies()
2918   target_common = common_ss.apply(config_target, strict: false)
2919   objects = common_all.extract_objects(target_common.sources())
2920   deps = target_common.dependencies()
2922   target_specific = specific_ss.apply(config_target, strict: false)
2923   arch_srcs += target_specific.sources()
2924   arch_deps += target_specific.dependencies()
2926   lib = static_library('qemu-' + target,
2927                  sources: arch_srcs + genh,
2928                  dependencies: arch_deps,
2929                  objects: objects,
2930                  include_directories: target_inc,
2931                  c_args: c_args,
2932                  build_by_default: false,
2933                  name_suffix: 'fa')
2935   if target.endswith('-softmmu')
2936     execs = [{
2937       'name': 'qemu-system-' + target_name,
2938       'win_subsystem': 'console',
2939       'sources': files('softmmu/main.c'),
2940       'dependencies': []
2941     }]
2942     if targetos == 'windows' and (sdl.found() or gtk.found())
2943       execs += [{
2944         'name': 'qemu-system-' + target_name + 'w',
2945         'win_subsystem': 'windows',
2946         'sources': files('softmmu/main.c'),
2947         'dependencies': []
2948       }]
2949     endif
2950     if get_option('fuzzing')
2951       specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
2952       execs += [{
2953         'name': 'qemu-fuzz-' + target_name,
2954         'win_subsystem': 'console',
2955         'sources': specific_fuzz.sources(),
2956         'dependencies': specific_fuzz.dependencies(),
2957       }]
2958     endif
2959   else
2960     execs = [{
2961       'name': 'qemu-' + target_name,
2962       'win_subsystem': 'console',
2963       'sources': [],
2964       'dependencies': []
2965     }]
2966   endif
2967   foreach exe: execs
2968     exe_name = exe['name']
2969     if targetos == 'darwin'
2970       exe_name += '-unsigned'
2971     endif
2973     emulator = executable(exe_name, exe['sources'],
2974                install: true,
2975                c_args: c_args,
2976                dependencies: arch_deps + deps + exe['dependencies'],
2977                objects: lib.extract_all_objects(recursive: true),
2978                link_language: link_language,
2979                link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
2980                link_args: link_args,
2981                win_subsystem: exe['win_subsystem'])
2983     if targetos == 'darwin'
2984       icon = 'pc-bios/qemu.rsrc'
2985       build_input = [emulator, files(icon)]
2986       install_input = [
2987         get_option('bindir') / exe_name,
2988         meson.current_source_dir() / icon
2989       ]
2990       if 'CONFIG_HVF' in config_target
2991         entitlements = 'accel/hvf/entitlements.plist'
2992         build_input += files(entitlements)
2993         install_input += meson.current_source_dir() / entitlements
2994       endif
2996       emulators += {exe['name'] : custom_target(exe['name'],
2997                    input: build_input,
2998                    output: exe['name'],
2999                    command: [
3000                      files('scripts/entitlement.sh'),
3001                      '@OUTPUT@',
3002                      '@INPUT@'
3003                    ])
3004       }
3006       meson.add_install_script('scripts/entitlement.sh', '--install',
3007                                get_option('bindir') / exe['name'],
3008                                install_input)
3009     else
3010       emulators += {exe['name']: emulator}
3011     endif
3013     if stap.found()
3014       foreach stp: [
3015         {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3016         {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3017         {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3018         {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3019       ]
3020         custom_target(exe['name'] + stp['ext'],
3021                       input: trace_events_all,
3022                       output: exe['name'] + stp['ext'],
3023                       install: stp['install'],
3024                       install_dir: get_option('datadir') / 'systemtap/tapset',
3025                       command: [
3026                         tracetool, '--group=all', '--format=' + stp['fmt'],
3027                         '--binary=' + stp['bin'],
3028                         '--target-name=' + target_name,
3029                         '--target-type=' + target_type,
3030                         '--probe-prefix=qemu.' + target_type + '.' + target_name,
3031                         '@INPUT@', '@OUTPUT@'
3032                       ],
3033                       depend_files: tracetool_depends)
3034       endforeach
3035     endif
3036   endforeach
3037 endforeach
3039 # Other build targets
3041 if 'CONFIG_PLUGIN' in config_host
3042   install_headers('include/qemu/qemu-plugin.h')
3043 endif
3045 if 'CONFIG_GUEST_AGENT' in config_host
3046   subdir('qga')
3047 elif get_option('guest_agent_msi').enabled()
3048   error('Guest agent MSI requested, but the guest agent is not being built')
3049 endif
3051 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3052 # when we don't build tools or system
3053 if xkbcommon.found()
3054   # used for the update-keymaps target, so include rules even if !have_tools
3055   qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3056                            dependencies: [qemuutil, xkbcommon], install: have_tools)
3057 endif
3059 if have_tools
3060   qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3061              dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3062   qemu_io = executable('qemu-io', files('qemu-io.c'),
3063              dependencies: [block, qemuutil], install: true)
3064   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3065                dependencies: [blockdev, qemuutil, gnutls], install: true)
3067   subdir('storage-daemon')
3068   subdir('contrib/rdmacm-mux')
3069   subdir('contrib/elf2dmp')
3071   executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3072              dependencies: qemuutil,
3073              install: true)
3075   if 'CONFIG_VHOST_USER' in config_host
3076     subdir('contrib/vhost-user-blk')
3077     subdir('contrib/vhost-user-gpu')
3078     subdir('contrib/vhost-user-input')
3079     subdir('contrib/vhost-user-scsi')
3080   endif
3082   if targetos == 'linux'
3083     executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3084                dependencies: [qemuutil, libcap_ng],
3085                install: true,
3086                install_dir: get_option('libexecdir'))
3088     executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3089                dependencies: [authz, crypto, io, qom, qemuutil,
3090                               libcap_ng, mpathpersist],
3091                install: true)
3092   endif
3094   if have_ivshmem
3095     subdir('contrib/ivshmem-client')
3096     subdir('contrib/ivshmem-server')
3097   endif
3098 endif
3100 subdir('scripts')
3101 subdir('tools')
3102 subdir('pc-bios')
3103 subdir('docs')
3104 subdir('tests')
3105 if gtk.found()
3106   subdir('po')
3107 endif
3109 if host_machine.system() == 'windows'
3110   nsis_cmd = [
3111     find_program('scripts/nsis.py'),
3112     '@OUTPUT@',
3113     get_option('prefix'),
3114     meson.current_source_dir(),
3115     host_machine.cpu(),
3116     '--',
3117     '-DDISPLAYVERSION=' + meson.project_version(),
3118   ]
3119   if build_docs
3120     nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3121   endif
3122   if gtk.found()
3123     nsis_cmd += '-DCONFIG_GTK=y'
3124   endif
3126   nsis = custom_target('nsis',
3127                        output: 'qemu-setup-' + meson.project_version() + '.exe',
3128                        input: files('qemu.nsi'),
3129                        build_always_stale: true,
3130                        command: nsis_cmd + ['@INPUT@'])
3131   alias_target('installer', nsis)
3132 endif
3134 #########################
3135 # Configuration summary #
3136 #########################
3138 # Directories
3139 summary_info = {}
3140 summary_info += {'Install prefix':    get_option('prefix')}
3141 summary_info += {'BIOS directory':    qemu_datadir}
3142 summary_info += {'firmware path':     get_option('qemu_firmwarepath')}
3143 summary_info += {'binary directory':  get_option('bindir')}
3144 summary_info += {'library directory': get_option('libdir')}
3145 summary_info += {'module directory':  qemu_moddir}
3146 summary_info += {'libexec directory': get_option('libexecdir')}
3147 summary_info += {'include directory': get_option('includedir')}
3148 summary_info += {'config directory':  get_option('sysconfdir')}
3149 if targetos != 'windows'
3150   summary_info += {'local state directory': get_option('localstatedir')}
3151   summary_info += {'Manual directory':      get_option('mandir')}
3152 else
3153   summary_info += {'local state directory': 'queried at runtime'}
3154 endif
3155 summary_info += {'Doc directory':     get_option('docdir')}
3156 summary_info += {'Build directory':   meson.current_build_dir()}
3157 summary_info += {'Source path':       meson.current_source_dir()}
3158 summary_info += {'GIT submodules':    config_host['GIT_SUBMODULES']}
3159 summary(summary_info, bool_yn: true, section: 'Directories')
3161 # Host binaries
3162 summary_info = {}
3163 summary_info += {'git':               config_host['GIT']}
3164 summary_info += {'make':              config_host['MAKE']}
3165 summary_info += {'python':            '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3166 summary_info += {'sphinx-build':      sphinx_build}
3167 if config_host.has_key('HAVE_GDB_BIN')
3168   summary_info += {'gdb':             config_host['HAVE_GDB_BIN']}
3169 endif
3170 summary_info += {'genisoimage':       config_host['GENISOIMAGE']}
3171 if targetos == 'windows' and config_host.has_key('CONFIG_GUEST_AGENT')
3172   summary_info += {'wixl':            wixl}
3173 endif
3174 if slirp_opt != 'disabled' and 'CONFIG_SLIRP_SMBD' in config_host
3175   summary_info += {'smbd':            config_host['CONFIG_SMBD_COMMAND']}
3176 endif
3177 summary(summary_info, bool_yn: true, section: 'Host binaries')
3179 # Configurable features
3180 summary_info = {}
3181 summary_info += {'Documentation':     build_docs}
3182 summary_info += {'system-mode emulation': have_system}
3183 summary_info += {'user-mode emulation': have_user}
3184 summary_info += {'block layer':       have_block}
3185 summary_info += {'Install blobs':     get_option('install_blobs')}
3186 summary_info += {'module support':    config_host.has_key('CONFIG_MODULES')}
3187 if config_host.has_key('CONFIG_MODULES')
3188   summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')}
3189 endif
3190 summary_info += {'fuzzing support':   get_option('fuzzing')}
3191 if have_system
3192   summary_info += {'Audio drivers':     ' '.join(audio_drivers_selected)}
3193 endif
3194 summary_info += {'Trace backends':    ','.join(get_option('trace_backends'))}
3195 if 'simple' in get_option('trace_backends')
3196   summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3197 endif
3198 summary_info += {'QOM debugging':     config_host.has_key('CONFIG_QOM_CAST_DEBUG')}
3199 summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')}
3200 summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')}
3201 summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')}
3202 summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')}
3203 summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')}
3204 summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')}
3205 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3206 summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')}
3207 summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')}
3208 summary_info += {'build guest agent': config_host.has_key('CONFIG_GUEST_AGENT')}
3209 summary(summary_info, bool_yn: true, section: 'Configurable features')
3211 # Compilation information
3212 summary_info = {}
3213 summary_info += {'host CPU':          cpu}
3214 summary_info += {'host endianness':   build_machine.endian()}
3215 summary_info += {'C compiler':        ' '.join(meson.get_compiler('c').cmd_array())}
3216 summary_info += {'Host C compiler':   ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3217 if link_language == 'cpp'
3218   summary_info += {'C++ compiler':    ' '.join(meson.get_compiler('cpp').cmd_array())}
3219 else
3220   summary_info += {'C++ compiler':      false}
3221 endif
3222 if targetos == 'darwin'
3223   summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3224 endif
3225 if targetos == 'windows'
3226   if 'WIN_SDK' in config_host
3227     summary_info += {'Windows SDK':   config_host['WIN_SDK']}
3228   endif
3229 endif
3230 summary_info += {'CFLAGS':            ' '.join(get_option('c_args')
3231                                                + ['-O' + get_option('optimization')]
3232                                                + (get_option('debug') ? ['-g'] : []))}
3233 if link_language == 'cpp'
3234   summary_info += {'CXXFLAGS':        ' '.join(get_option('cpp_args')
3235                                                + ['-O' + get_option('optimization')]
3236                                                + (get_option('debug') ? ['-g'] : []))}
3237 endif
3238 link_args = get_option(link_language + '_link_args')
3239 if link_args.length() > 0
3240   summary_info += {'LDFLAGS':         ' '.join(link_args)}
3241 endif
3242 summary_info += {'QEMU_CFLAGS':       config_host['QEMU_CFLAGS']}
3243 summary_info += {'QEMU_LDFLAGS':      config_host['QEMU_LDFLAGS']}
3244 summary_info += {'profiler':          config_host.has_key('CONFIG_PROFILER')}
3245 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3246 summary_info += {'PIE':               get_option('b_pie')}
3247 summary_info += {'static build':      config_host.has_key('CONFIG_STATIC')}
3248 summary_info += {'malloc trim support': has_malloc_trim}
3249 summary_info += {'membarrier':        config_host.has_key('CONFIG_MEMBARRIER')}
3250 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
3251 summary_info += {'mutex debugging':   config_host.has_key('CONFIG_DEBUG_MUTEX')}
3252 summary_info += {'memory allocator':  get_option('malloc')}
3253 summary_info += {'avx2 optimization': config_host.has_key('CONFIG_AVX2_OPT')}
3254 summary_info += {'avx512f optimization': config_host.has_key('CONFIG_AVX512F_OPT')}
3255 summary_info += {'gprof enabled':     config_host.has_key('CONFIG_GPROF')}
3256 summary_info += {'gcov':              get_option('b_coverage')}
3257 summary_info += {'thread sanitizer':  config_host.has_key('CONFIG_TSAN')}
3258 summary_info += {'CFI support':       get_option('cfi')}
3259 if get_option('cfi')
3260   summary_info += {'CFI debug support': get_option('cfi_debug')}
3261 endif
3262 summary_info += {'strip binaries':    get_option('strip')}
3263 summary_info += {'sparse':            sparse}
3264 summary_info += {'mingw32 support':   targetos == 'windows'}
3266 # snarf the cross-compilation information for tests
3267 foreach target: target_dirs
3268   tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3269   if fs.exists(tcg_mak)
3270     config_cross_tcg = keyval.load(tcg_mak)
3271     target = config_cross_tcg['TARGET_NAME']
3272     compiler = ''
3273     if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg
3274       summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] +
3275                                           ' via ' + config_cross_tcg['DOCKER_IMAGE']}
3276     elif 'CROSS_CC_GUEST' in config_cross_tcg
3277       summary_info += {target + ' tests'
3278                                 : config_cross_tcg['CROSS_CC_GUEST'] }
3279     endif
3280    endif
3281 endforeach
3283 summary(summary_info, bool_yn: true, section: 'Compilation')
3285 # Targets and accelerators
3286 summary_info = {}
3287 if have_system
3288   summary_info += {'KVM support':       config_all.has_key('CONFIG_KVM')}
3289   summary_info += {'HAX support':       config_all.has_key('CONFIG_HAX')}
3290   summary_info += {'HVF support':       config_all.has_key('CONFIG_HVF')}
3291   summary_info += {'WHPX support':      config_all.has_key('CONFIG_WHPX')}
3292   summary_info += {'NVMM support':      config_all.has_key('CONFIG_NVMM')}
3293   summary_info += {'Xen support':       config_host.has_key('CONFIG_XEN_BACKEND')}
3294   if config_host.has_key('CONFIG_XEN_BACKEND')
3295     summary_info += {'xen ctrl version':  config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']}
3296   endif
3297 endif
3298 summary_info += {'TCG support':       config_all.has_key('CONFIG_TCG')}
3299 if config_all.has_key('CONFIG_TCG')
3300   if get_option('tcg_interpreter')
3301     summary_info += {'TCG backend':   'TCI (TCG with bytecode interpreter, experimental and slow)'}
3302   else
3303     summary_info += {'TCG backend':   'native (@0@)'.format(cpu)}
3304   endif
3305   summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3306   summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3307 endif
3308 summary_info += {'target list':       ' '.join(target_dirs)}
3309 if have_system
3310   summary_info += {'default devices':   get_option('default_devices')}
3311   summary_info += {'out of process emulation': multiprocess_allowed}
3312 endif
3313 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3315 # Block layer
3316 summary_info = {}
3317 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3318 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
3319 if have_block
3320   summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']}
3321   summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']}
3322   summary_info += {'Use block whitelist in tools': config_host.has_key('CONFIG_BDRV_WHITELIST_TOOLS')}
3323   summary_info += {'VirtFS support':    have_virtfs}
3324   summary_info += {'build virtiofs daemon': have_virtiofsd}
3325   summary_info += {'Live block migration': config_host.has_key('CONFIG_LIVE_BLOCK_MIGRATION')}
3326   summary_info += {'replication support': config_host.has_key('CONFIG_REPLICATION')}
3327   summary_info += {'bochs support':     config_host.has_key('CONFIG_BOCHS')}
3328   summary_info += {'cloop support':     config_host.has_key('CONFIG_CLOOP')}
3329   summary_info += {'dmg support':       config_host.has_key('CONFIG_DMG')}
3330   summary_info += {'qcow v1 support':   config_host.has_key('CONFIG_QCOW1')}
3331   summary_info += {'vdi support':       config_host.has_key('CONFIG_VDI')}
3332   summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
3333   summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
3334   summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
3335   summary_info += {'FUSE exports':      fuse}
3336 endif
3337 summary(summary_info, bool_yn: true, section: 'Block layer support')
3339 # Crypto
3340 summary_info = {}
3341 summary_info += {'TLS priority':      config_host['CONFIG_TLS_PRIORITY']}
3342 summary_info += {'GNUTLS support':    gnutls}
3343 if gnutls.found()
3344   summary_info += {'  GNUTLS crypto':   gnutls_crypto.found()}
3345 endif
3346 summary_info += {'libgcrypt':         gcrypt}
3347 summary_info += {'nettle':            nettle}
3348 if nettle.found()
3349    summary_info += {'  XTS':             xts != 'private'}
3350 endif
3351 summary_info += {'crypto afalg':      config_host.has_key('CONFIG_AF_ALG')}
3352 summary_info += {'rng-none':          config_host.has_key('CONFIG_RNG_NONE')}
3353 summary_info += {'Linux keyring':     config_host.has_key('CONFIG_SECRET_KEYRING')}
3354 summary(summary_info, bool_yn: true, section: 'Crypto')
3356 # Libraries
3357 summary_info = {}
3358 if targetos == 'darwin'
3359   summary_info += {'Cocoa support':   cocoa}
3360 endif
3361 summary_info += {'SDL support':       sdl}
3362 summary_info += {'SDL image support': sdl_image}
3363 summary_info += {'GTK support':       gtk}
3364 summary_info += {'pixman':            pixman}
3365 summary_info += {'VTE support':       vte}
3366 summary_info += {'slirp support':     slirp_opt == 'internal' ? slirp_opt : slirp}
3367 summary_info += {'libtasn1':          tasn1}
3368 summary_info += {'PAM':               pam}
3369 summary_info += {'iconv support':     iconv}
3370 summary_info += {'curses support':    curses}
3371 summary_info += {'virgl support':     virgl}
3372 summary_info += {'curl support':      curl}
3373 summary_info += {'Multipath support': mpathpersist}
3374 summary_info += {'VNC support':       vnc}
3375 if vnc.found()
3376   summary_info += {'VNC SASL support':  sasl}
3377   summary_info += {'VNC JPEG support':  jpeg}
3378   summary_info += {'VNC PNG support':   png}
3379 endif
3380 if targetos not in ['darwin', 'haiku', 'windows']
3381   summary_info += {'OSS support':     oss}
3382 elif targetos == 'darwin'
3383   summary_info += {'CoreAudio support': coreaudio}
3384 elif targetos == 'windows'
3385   summary_info += {'DirectSound support': dsound}
3386 endif
3387 if targetos == 'linux'
3388   summary_info += {'ALSA support':    alsa}
3389   summary_info += {'PulseAudio support': pulse}
3390 endif
3391 summary_info += {'JACK support':      jack}
3392 summary_info += {'brlapi support':    brlapi}
3393 summary_info += {'vde support':       vde}
3394 summary_info += {'netmap support':    have_netmap}
3395 summary_info += {'Linux AIO support': libaio}
3396 summary_info += {'Linux io_uring support': linux_io_uring}
3397 summary_info += {'ATTR/XATTR support': libattr}
3398 summary_info += {'RDMA support':      config_host.has_key('CONFIG_RDMA')}
3399 summary_info += {'PVRDMA support':    config_host.has_key('CONFIG_PVRDMA')}
3400 summary_info += {'fdt support':       fdt_opt == 'disabled' ? false : fdt_opt}
3401 summary_info += {'libcap-ng support': libcap_ng}
3402 summary_info += {'bpf support':       libbpf}
3403 summary_info += {'spice protocol support': spice_protocol}
3404 if spice_protocol.found()
3405   summary_info += {'  spice server support': spice}
3406 endif
3407 summary_info += {'rbd support':       rbd}
3408 summary_info += {'xfsctl support':    config_host.has_key('CONFIG_XFS')}
3409 summary_info += {'smartcard support': cacard}
3410 summary_info += {'U2F support':       u2f}
3411 summary_info += {'libusb':            libusb}
3412 summary_info += {'usb net redir':     usbredir}
3413 summary_info += {'OpenGL support':    config_host.has_key('CONFIG_OPENGL')}
3414 summary_info += {'GBM':               gbm}
3415 summary_info += {'libiscsi support':  libiscsi}
3416 summary_info += {'libnfs support':    libnfs}
3417 if targetos == 'windows'
3418   if config_host.has_key('CONFIG_GUEST_AGENT')
3419     summary_info += {'QGA VSS support':   config_host.has_key('CONFIG_QGA_VSS')}
3420     summary_info += {'QGA w32 disk info': config_host.has_key('CONFIG_QGA_NTDDSCSI')}
3421   endif
3422 endif
3423 summary_info += {'seccomp support':   seccomp}
3424 summary_info += {'GlusterFS support': glusterfs}
3425 summary_info += {'TPM support':       config_host.has_key('CONFIG_TPM')}
3426 summary_info += {'libssh support':    config_host.has_key('CONFIG_LIBSSH')}
3427 summary_info += {'lzo support':       lzo}
3428 summary_info += {'snappy support':    snappy}
3429 summary_info += {'bzip2 support':     libbzip2}
3430 summary_info += {'lzfse support':     liblzfse}
3431 summary_info += {'zstd support':      zstd}
3432 summary_info += {'NUMA host support': config_host.has_key('CONFIG_NUMA')}
3433 summary_info += {'libxml2':           libxml2}
3434 summary_info += {'capstone':          capstone_opt == 'internal' ? capstone_opt : capstone}
3435 summary_info += {'libpmem support':   libpmem}
3436 summary_info += {'libdaxctl support': libdaxctl}
3437 summary_info += {'libudev':           libudev}
3438 # Dummy dependency, keep .found()
3439 summary_info += {'FUSE lseek':        fuse_lseek.found()}
3440 summary(summary_info, bool_yn: true, section: 'Dependencies')
3442 if not supported_cpus.contains(cpu)
3443   message()
3444   warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3445   message()
3446   message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3447   message('The QEMU project intends to remove support for this host CPU in')
3448   message('a future release if nobody volunteers to maintain it and to')
3449   message('provide a build host for our continuous integration setup.')
3450   message('configure has succeeded and you can continue to build, but')
3451   message('if you care about QEMU on this platform you should contact')
3452   message('us upstream at qemu-devel@nongnu.org.')
3453 endif
3455 if not supported_oses.contains(targetos)
3456   message()
3457   warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
3458   message()
3459   message('Host OS ' + targetos + 'support is not currently maintained.')
3460   message('The QEMU project intends to remove support for this host OS in')
3461   message('a future release if nobody volunteers to maintain it and to')
3462   message('provide a build host for our continuous integration setup.')
3463   message('configure has succeeded and you can continue to build, but')
3464   message('if you care about QEMU on this platform you should contact')
3465   message('us upstream at qemu-devel@nongnu.org.')
3466 endif