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