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