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