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