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