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