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