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