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