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