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