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