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