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