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