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