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