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