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