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