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