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