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