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