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