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