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