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