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