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