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