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