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