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