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