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