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