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