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