]> git.proxmox.com Git - mirror_qemu.git/blob - meson.build
ui/clipboard: reset the serial state on reset
[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 meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
11
12 not_found = dependency('', required: false)
13 keyval = import('keyval')
14 ss = import('sourceset')
15 fs = import('fs')
16
17 sh = find_program('sh')
18 cc = meson.get_compiler('c')
19 config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
20 enable_modules = 'CONFIG_MODULES' in config_host
21 enable_static = 'CONFIG_STATIC' in config_host
22
23 # Allow both shared and static libraries unless --enable-static
24 static_kwargs = enable_static ? {'static': true} : {}
25
26 # Temporary directory used for files created while
27 # configure runs. Since it is in the build directory
28 # we can safely blow away any previous version of it
29 # (and we need not jump through hoops to try to delete
30 # it when configure exits.)
31 tmpdir = meson.current_build_dir() / 'meson-private/temp'
32
33 if get_option('qemu_suffix').startswith('/')
34 error('qemu_suffix cannot start with a /')
35 endif
36
37 qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix')
38 qemu_datadir = get_option('datadir') / get_option('qemu_suffix')
39 qemu_docdir = get_option('docdir') / get_option('qemu_suffix')
40 qemu_moddir = get_option('libdir') / get_option('qemu_suffix')
41
42 qemu_desktopdir = get_option('datadir') / 'applications'
43 qemu_icondir = get_option('datadir') / 'icons'
44
45 config_host_data = configuration_data()
46 genh = []
47 qapi_trace_events = []
48
49 bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
50 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
51 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
52 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
53
54 cpu = host_machine.cpu_family()
55
56 # Unify riscv* to a single family.
57 if cpu in ['riscv32', 'riscv64']
58 cpu = 'riscv'
59 endif
60
61 targetos = host_machine.system()
62
63 target_dirs = config_host['TARGET_DIRS'].split()
64 have_linux_user = false
65 have_bsd_user = false
66 have_system = false
67 foreach target : target_dirs
68 have_linux_user = have_linux_user or target.endswith('linux-user')
69 have_bsd_user = have_bsd_user or target.endswith('bsd-user')
70 have_system = have_system or target.endswith('-softmmu')
71 endforeach
72 have_user = have_linux_user or have_bsd_user
73 have_tools = get_option('tools') \
74 .disable_auto_if(not have_system) \
75 .allowed()
76 have_ga = get_option('guest_agent') \
77 .disable_auto_if(not have_system and not have_tools) \
78 .require(targetos in ['sunos', 'linux', 'windows'],
79 error_message: 'unsupported OS for QEMU guest agent') \
80 .allowed()
81 have_block = have_system or have_tools
82
83 python = import('python').find_installation()
84
85 if cpu not in supported_cpus
86 host_arch = 'unknown'
87 elif cpu == 'x86'
88 host_arch = 'i386'
89 elif cpu == 'mips64'
90 host_arch = 'mips'
91 else
92 host_arch = cpu
93 endif
94
95 if cpu in ['x86', 'x86_64']
96 kvm_targets = ['i386-softmmu', 'x86_64-softmmu']
97 elif cpu == 'aarch64'
98 kvm_targets = ['aarch64-softmmu']
99 elif cpu == 's390x'
100 kvm_targets = ['s390x-softmmu']
101 elif cpu in ['ppc', 'ppc64']
102 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
103 elif cpu in ['mips', 'mips64']
104 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
105 elif cpu in ['riscv']
106 kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
107 else
108 kvm_targets = []
109 endif
110
111 kvm_targets_c = '""'
112 if get_option('kvm').allowed() and targetos == 'linux'
113 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"'
114 endif
115 config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c)
116
117 accelerator_targets = { 'CONFIG_KVM': kvm_targets }
118
119 if cpu in ['aarch64']
120 accelerator_targets += {
121 'CONFIG_HVF': ['aarch64-softmmu']
122 }
123 endif
124
125 if cpu in ['x86', 'x86_64', 'arm', 'aarch64']
126 # i386 emulator provides xenpv machine type for multiple architectures
127 accelerator_targets += {
128 'CONFIG_XEN': ['i386-softmmu', 'x86_64-softmmu'],
129 }
130 endif
131 if cpu in ['x86', 'x86_64']
132 accelerator_targets += {
133 'CONFIG_HAX': ['i386-softmmu', 'x86_64-softmmu'],
134 'CONFIG_HVF': ['x86_64-softmmu'],
135 'CONFIG_NVMM': ['i386-softmmu', 'x86_64-softmmu'],
136 'CONFIG_WHPX': ['i386-softmmu', 'x86_64-softmmu'],
137 }
138 endif
139
140 modular_tcg = []
141 # Darwin does not support references to thread-local variables in modules
142 if targetos != 'darwin'
143 modular_tcg = ['i386-softmmu', 'x86_64-softmmu']
144 endif
145
146 edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ]
147 unpack_edk2_blobs = false
148 foreach target : edk2_targets
149 if target in target_dirs
150 bzip2 = find_program('bzip2', required: get_option('install_blobs'))
151 unpack_edk2_blobs = bzip2.found()
152 break
153 endif
154 endforeach
155
156 dtrace = not_found
157 stap = not_found
158 if 'dtrace' in get_option('trace_backends')
159 dtrace = find_program('dtrace', required: true)
160 stap = find_program('stap', required: false)
161 if stap.found()
162 # Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
163 # visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
164 # instead. QEMU --enable-modules depends on this because the SystemTap
165 # semaphores are linked into the main binary and not the module's shared
166 # object.
167 add_global_arguments('-DSTAP_SDT_V2',
168 native: false, language: ['c', 'cpp', 'objc'])
169 endif
170 endif
171
172 if get_option('iasl') == ''
173 iasl = find_program('iasl', required: false)
174 else
175 iasl = find_program(get_option('iasl'), required: true)
176 endif
177
178 ##################
179 # Compiler flags #
180 ##################
181
182 qemu_cflags = config_host['QEMU_CFLAGS'].split()
183 qemu_cxxflags = config_host['QEMU_CXXFLAGS'].split()
184 qemu_objcflags = config_host['QEMU_OBJCFLAGS'].split()
185 qemu_ldflags = config_host['QEMU_LDFLAGS'].split()
186
187 if targetos == 'windows'
188 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--no-seh', '-Wl,--nxcompat')
189 # Disable ASLR for debug builds to allow debugging with gdb
190 if get_option('optimization') == '0'
191 qemu_ldflags += cc.get_supported_link_arguments('-Wl,--dynamicbase')
192 endif
193 endif
194
195 if get_option('gprof')
196 qemu_cflags += ['-p']
197 qemu_cxxflags += ['-p']
198 qemu_objcflags += ['-p']
199 qemu_ldflags += ['-p']
200 endif
201
202 # Specify linker-script with add_project_link_arguments so that it is not placed
203 # within a linker --start-group/--end-group pair
204 if get_option('fuzzing')
205 add_project_link_arguments(['-Wl,-T,',
206 (meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
207 native: false, language: ['c', 'cpp', 'objc'])
208
209 # Specify a filter to only instrument code that is directly related to
210 # virtual-devices.
211 configure_file(output: 'instrumentation-filter',
212 input: 'scripts/oss-fuzz/instrumentation-filter-template',
213 copy: true)
214
215 if cc.compiles('int main () { return 0; }',
216 name: '-fsanitize-coverage-allowlist=/dev/null',
217 args: ['-fsanitize-coverage-allowlist=/dev/null',
218 '-fsanitize-coverage=trace-pc'] )
219 add_global_arguments('-fsanitize-coverage-allowlist=instrumentation-filter',
220 native: false, language: ['c', 'cpp', 'objc'])
221 endif
222
223 if get_option('fuzzing_engine') == ''
224 # Add CFLAGS to tell clang to add fuzzer-related instrumentation to all the
225 # compiled code. To build non-fuzzer binaries with --enable-fuzzing, link
226 # everything with fsanitize=fuzzer-no-link. Otherwise, the linker will be
227 # unable to bind the fuzzer-related callbacks added by instrumentation.
228 add_global_arguments('-fsanitize=fuzzer-no-link',
229 native: false, language: ['c', 'cpp', 'objc'])
230 add_global_link_arguments('-fsanitize=fuzzer-no-link',
231 native: false, language: ['c', 'cpp', 'objc'])
232 # For the actual fuzzer binaries, we need to link against the libfuzzer
233 # library. They need to be configurable, to support OSS-Fuzz
234 fuzz_exe_ldflags = ['-fsanitize=fuzzer']
235 else
236 # LIB_FUZZING_ENGINE was set; assume we are running on OSS-Fuzz, and
237 # the needed CFLAGS have already been provided
238 fuzz_exe_ldflags = get_option('fuzzing_engine').split()
239 endif
240 endif
241
242 add_global_arguments(qemu_cflags, native: false, language: ['c'])
243 add_global_arguments(qemu_cxxflags, native: false, language: ['cpp'])
244 add_global_arguments(qemu_objcflags, native: false, language: ['objc'])
245 add_global_link_arguments(qemu_ldflags, native: false, language: ['c', 'cpp', 'objc'])
246
247 if targetos == 'linux'
248 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers',
249 '-isystem', 'linux-headers',
250 language: ['c', 'cpp'])
251 endif
252
253 add_project_arguments('-iquote', '.',
254 '-iquote', meson.current_source_dir(),
255 '-iquote', meson.current_source_dir() / 'include',
256 language: ['c', 'cpp', 'objc'])
257
258 link_language = meson.get_external_property('link_language', 'cpp')
259 if link_language == 'cpp'
260 add_languages('cpp', required: true, native: false)
261 cxx = meson.get_compiler('cpp')
262 linker = cxx
263 else
264 linker = cc
265 endif
266 if host_machine.system() == 'darwin'
267 add_languages('objc', required: false, native: false)
268 endif
269
270 sparse = find_program('cgcc', required: get_option('sparse'))
271 if sparse.found()
272 run_target('sparse',
273 command: [find_program('scripts/check_sparse.py'),
274 'compile_commands.json', sparse.full_path(), '-Wbitwise',
275 '-Wno-transparent-union', '-Wno-old-initializer',
276 '-Wno-non-pointer-null'])
277 endif
278
279 ###########################################
280 # Target-specific checks and dependencies #
281 ###########################################
282
283 # Fuzzing
284 if get_option('fuzzing') and get_option('fuzzing_engine') == '' and \
285 not cc.links('''
286 #include <stdint.h>
287 #include <sys/types.h>
288 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
289 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; }
290 ''',
291 args: ['-Werror', '-fsanitize=fuzzer'])
292 error('Your compiler does not support -fsanitize=fuzzer')
293 endif
294
295 # Tracing backends
296 if 'ftrace' in get_option('trace_backends') and targetos != 'linux'
297 error('ftrace is supported only on Linux')
298 endif
299 if 'syslog' in get_option('trace_backends') and not cc.compiles('''
300 #include <syslog.h>
301 int main(void) {
302 openlog("qemu", LOG_PID, LOG_DAEMON);
303 syslog(LOG_INFO, "configure");
304 return 0;
305 }''')
306 error('syslog is not supported on this system')
307 endif
308
309 # Miscellaneous Linux-only features
310 get_option('mpath') \
311 .require(targetos == 'linux', error_message: 'Multipath is supported only on Linux')
312
313 multiprocess_allowed = get_option('multiprocess') \
314 .require(targetos == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \
315 .allowed()
316
317 vfio_user_server_allowed = get_option('vfio_user_server') \
318 .require(targetos == 'linux', error_message: 'vfio-user server is supported only on Linux') \
319 .allowed()
320
321 have_tpm = get_option('tpm') \
322 .require(targetos != 'windows', error_message: 'TPM emulation only available on POSIX systems') \
323 .allowed()
324
325 # vhost
326 have_vhost_user = get_option('vhost_user') \
327 .disable_auto_if(targetos != 'linux') \
328 .require(targetos != 'windows',
329 error_message: 'vhost-user is not available on Windows').allowed()
330 have_vhost_vdpa = get_option('vhost_vdpa') \
331 .require(targetos == 'linux',
332 error_message: 'vhost-vdpa is only available on Linux').allowed()
333 have_vhost_kernel = get_option('vhost_kernel') \
334 .require(targetos == 'linux',
335 error_message: 'vhost-kernel is only available on Linux').allowed()
336 have_vhost_user_crypto = get_option('vhost_crypto') \
337 .require(have_vhost_user,
338 error_message: 'vhost-crypto requires vhost-user to be enabled').allowed()
339
340 have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel
341
342 have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed()
343 have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed()
344 have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed()
345 have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa
346
347 # Target-specific libraries and flags
348 libm = cc.find_library('m', required: false)
349 threads = dependency('threads')
350 util = cc.find_library('util', required: false)
351 winmm = []
352 socket = []
353 version_res = []
354 coref = []
355 iokit = []
356 emulator_link_args = []
357 nvmm =not_found
358 hvf = not_found
359 midl = not_found
360 widl = not_found
361 pathcch = not_found
362 host_dsosuf = '.so'
363 if targetos == 'windows'
364 midl = find_program('midl', required: false)
365 widl = find_program('widl', required: false)
366 pathcch = cc.find_library('pathcch')
367 socket = cc.find_library('ws2_32')
368 winmm = cc.find_library('winmm')
369
370 win = import('windows')
371 version_res = win.compile_resources('version.rc',
372 depend_files: files('pc-bios/qemu-nsis.ico'),
373 include_directories: include_directories('.'))
374 host_dsosuf = '.dll'
375 elif targetos == 'darwin'
376 coref = dependency('appleframeworks', modules: 'CoreFoundation')
377 iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
378 host_dsosuf = '.dylib'
379 elif targetos == 'sunos'
380 socket = [cc.find_library('socket'),
381 cc.find_library('nsl'),
382 cc.find_library('resolv')]
383 elif targetos == 'haiku'
384 socket = [cc.find_library('posix_error_mapper'),
385 cc.find_library('network'),
386 cc.find_library('bsd')]
387 elif targetos == 'openbsd'
388 if get_option('tcg').allowed() and target_dirs.length() > 0
389 # Disable OpenBSD W^X if available
390 emulator_link_args = cc.get_supported_link_arguments('-Wl,-z,wxneeded')
391 endif
392 endif
393
394 # Target-specific configuration of accelerators
395 accelerators = []
396 if get_option('kvm').allowed() and targetos == 'linux'
397 accelerators += 'CONFIG_KVM'
398 endif
399 if get_option('whpx').allowed() and targetos == 'windows'
400 if get_option('whpx').enabled() and host_machine.cpu() != 'x86_64'
401 error('WHPX requires 64-bit host')
402 elif cc.has_header('WinHvPlatform.h', required: get_option('whpx')) and \
403 cc.has_header('WinHvEmulation.h', required: get_option('whpx'))
404 accelerators += 'CONFIG_WHPX'
405 endif
406 endif
407 if get_option('hvf').allowed()
408 hvf = dependency('appleframeworks', modules: 'Hypervisor',
409 required: get_option('hvf'))
410 if hvf.found()
411 accelerators += 'CONFIG_HVF'
412 endif
413 endif
414 if get_option('hax').allowed()
415 if get_option('hax').enabled() or targetos in ['windows', 'darwin', 'netbsd']
416 accelerators += 'CONFIG_HAX'
417 endif
418 endif
419 if targetos == 'netbsd'
420 nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
421 if nvmm.found()
422 accelerators += 'CONFIG_NVMM'
423 endif
424 endif
425
426 tcg_arch = host_arch
427 if get_option('tcg').allowed()
428 if host_arch == 'unknown'
429 if get_option('tcg_interpreter')
430 warning('Unsupported CPU @0@, will use TCG with TCI (slow)'.format(cpu))
431 else
432 error('Unsupported CPU @0@, try --enable-tcg-interpreter'.format(cpu))
433 endif
434 elif get_option('tcg_interpreter')
435 warning('Use of the TCG interpreter is not recommended on this host')
436 warning('architecture. There is a native TCG execution backend available')
437 warning('which provides substantially better performance and reliability.')
438 warning('It is strongly recommended to remove the --enable-tcg-interpreter')
439 warning('configuration option on this architecture to use the native')
440 warning('backend.')
441 endif
442 if get_option('tcg_interpreter')
443 tcg_arch = 'tci'
444 elif host_arch == 'sparc64'
445 tcg_arch = 'sparc'
446 elif host_arch == 'x86_64'
447 tcg_arch = 'i386'
448 elif host_arch == 'ppc64'
449 tcg_arch = 'ppc'
450 endif
451 add_project_arguments('-iquote', meson.current_source_dir() / 'tcg' / tcg_arch,
452 language: ['c', 'cpp', 'objc'])
453
454 accelerators += 'CONFIG_TCG'
455 config_host += { 'CONFIG_TCG': 'y' }
456 endif
457
458 if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled()
459 error('KVM not available on this platform')
460 endif
461 if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled()
462 error('HVF not available on this platform')
463 endif
464 if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled()
465 error('NVMM not available on this platform')
466 endif
467 if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled()
468 error('WHPX not available on this platform')
469 endif
470
471 ################
472 # Dependencies #
473 ################
474
475 # The path to glib.h is added to all compilation commands. This was
476 # grandfathered in from the QEMU Makefiles.
477 add_project_arguments(config_host['GLIB_CFLAGS'].split(),
478 native: false, language: ['c', 'cpp', 'objc'])
479 glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
480 link_args: config_host['GLIB_LIBS'].split(),
481 version: config_host['GLIB_VERSION'],
482 variables: {
483 'bindir': config_host['GLIB_BINDIR'],
484 })
485 # override glib dep with the configure results (for subprojects)
486 meson.override_dependency('glib-2.0', glib)
487
488 gio = not_found
489 gdbus_codegen = not_found
490 if not get_option('gio').auto() or have_system
491 gio = dependency('gio-2.0', required: get_option('gio'),
492 method: 'pkg-config', kwargs: static_kwargs)
493 if gio.found() and not cc.links('''
494 #include <gio/gio.h>
495 int main(void)
496 {
497 g_dbus_proxy_new_sync(0, 0, 0, 0, 0, 0, 0, 0);
498 return 0;
499 }''', dependencies: [glib, gio])
500 if get_option('gio').enabled()
501 error('The installed libgio is broken for static linking')
502 endif
503 gio = not_found
504 endif
505 if gio.found()
506 gdbus_codegen = find_program(gio.get_variable('gdbus_codegen'),
507 required: get_option('gio'))
508 gio_unix = dependency('gio-unix-2.0', required: get_option('gio'),
509 method: 'pkg-config', kwargs: static_kwargs)
510 gio = declare_dependency(dependencies: [gio, gio_unix],
511 version: gio.version())
512 endif
513 endif
514
515 lttng = not_found
516 if 'ust' in get_option('trace_backends')
517 lttng = dependency('lttng-ust', required: true, version: '>= 2.1',
518 method: 'pkg-config', kwargs: static_kwargs)
519 endif
520 pixman = not_found
521 if have_system or have_tools
522 pixman = dependency('pixman-1', required: have_system, version:'>=0.21.8',
523 method: 'pkg-config', kwargs: static_kwargs)
524 endif
525 zlib = dependency('zlib', required: true, kwargs: static_kwargs)
526
527 libaio = not_found
528 if not get_option('linux_aio').auto() or have_block
529 libaio = cc.find_library('aio', has_headers: ['libaio.h'],
530 required: get_option('linux_aio'),
531 kwargs: static_kwargs)
532 endif
533
534 linux_io_uring_test = '''
535 #include <liburing.h>
536 #include <linux/errqueue.h>
537
538 int main(void) { return 0; }'''
539
540 linux_io_uring = not_found
541 if not get_option('linux_io_uring').auto() or have_block
542 linux_io_uring = dependency('liburing', version: '>=0.3',
543 required: get_option('linux_io_uring'),
544 method: 'pkg-config', kwargs: static_kwargs)
545 if not cc.links(linux_io_uring_test)
546 linux_io_uring = not_found
547 endif
548 endif
549
550 libnfs = not_found
551 if not get_option('libnfs').auto() or have_block
552 libnfs = dependency('libnfs', version: '>=1.9.3',
553 required: get_option('libnfs'),
554 method: 'pkg-config', kwargs: static_kwargs)
555 endif
556
557 libattr_test = '''
558 #include <stddef.h>
559 #include <sys/types.h>
560 #ifdef CONFIG_LIBATTR
561 #include <attr/xattr.h>
562 #else
563 #include <sys/xattr.h>
564 #endif
565 int main(void) { getxattr(NULL, NULL, NULL, 0); setxattr(NULL, NULL, NULL, 0, 0); return 0; }'''
566
567 libattr = not_found
568 have_old_libattr = false
569 if get_option('attr').allowed()
570 if cc.links(libattr_test)
571 libattr = declare_dependency()
572 else
573 libattr = cc.find_library('attr', has_headers: ['attr/xattr.h'],
574 required: get_option('attr'),
575 kwargs: static_kwargs)
576 if libattr.found() and not \
577 cc.links(libattr_test, dependencies: libattr, args: '-DCONFIG_LIBATTR')
578 libattr = not_found
579 if get_option('attr').enabled()
580 error('could not link libattr')
581 else
582 warning('could not link libattr, disabling')
583 endif
584 else
585 have_old_libattr = libattr.found()
586 endif
587 endif
588 endif
589
590 cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
591 required: get_option('cocoa'))
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
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 opengl.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
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 .require(opengl.found() and gbm.found(),
1675 error_message: '-display dbus requires epoxy/egl and gbm') \
1676 .allowed()
1677
1678 have_virtfs = get_option('virtfs') \
1679 .require(targetos == 'linux' or targetos == 'darwin',
1680 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \
1681 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'),
1682 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \
1683 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()),
1684 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \
1685 .disable_auto_if(not have_tools and not have_system) \
1686 .allowed()
1687
1688 have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools
1689
1690 if get_option('block_drv_ro_whitelist') == ''
1691 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '')
1692 else
1693 config_host_data.set('CONFIG_BDRV_RO_WHITELIST',
1694 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ')
1695 endif
1696 if get_option('block_drv_rw_whitelist') == ''
1697 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '')
1698 else
1699 config_host_data.set('CONFIG_BDRV_RW_WHITELIST',
1700 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ')
1701 endif
1702
1703 foreach k : get_option('trace_backends')
1704 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true)
1705 endforeach
1706 config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file'))
1707 config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority'))
1708 if iasl.found()
1709 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path())
1710 endif
1711 config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir'))
1712 config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix'))
1713 config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir)
1714 config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir)
1715 config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir)
1716
1717 qemu_firmwarepath = ''
1718 foreach k : get_option('qemu_firmwarepath')
1719 qemu_firmwarepath += '"' + get_option('prefix') / k + '", '
1720 endforeach
1721 config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath)
1722
1723 config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir'))
1724 config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir)
1725 config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir'))
1726 config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir'))
1727 config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir)
1728 config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir'))
1729
1730 if config_host.has_key('CONFIG_MODULES')
1731 config_host_data.set('CONFIG_STAMP', run_command(
1732 meson.current_source_dir() / 'scripts/qemu-stamp.py',
1733 meson.project_version(), get_option('pkgversion'), '--',
1734 meson.current_source_dir() / 'configure',
1735 capture: true, check: true).stdout().strip())
1736 endif
1737
1738 have_slirp_smbd = get_option('slirp_smbd') \
1739 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \
1740 .allowed()
1741 if have_slirp_smbd
1742 smbd_path = get_option('smbd')
1743 if smbd_path == ''
1744 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd')
1745 endif
1746 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path)
1747 endif
1748
1749 config_host_data.set('HOST_' + host_arch.to_upper(), 1)
1750
1751 if get_option('module_upgrades') and not enable_modules
1752 error('Cannot enable module-upgrades as modules are not enabled')
1753 endif
1754 config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades'))
1755
1756 config_host_data.set('CONFIG_ATTR', libattr.found())
1757 config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools'))
1758 config_host_data.set('CONFIG_BRLAPI', brlapi.found())
1759 config_host_data.set('CONFIG_COCOA', cocoa.found())
1760 config_host_data.set('CONFIG_FUZZ', get_option('fuzzing'))
1761 config_host_data.set('CONFIG_GCOV', get_option('b_coverage'))
1762 config_host_data.set('CONFIG_LIBUDEV', libudev.found())
1763 config_host_data.set('CONFIG_LZO', lzo.found())
1764 config_host_data.set('CONFIG_MPATH', mpathpersist.found())
1765 config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api)
1766 config_host_data.set('CONFIG_CURL', curl.found())
1767 config_host_data.set('CONFIG_CURSES', curses.found())
1768 config_host_data.set('CONFIG_GBM', gbm.found())
1769 config_host_data.set('CONFIG_GIO', gio.found())
1770 config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found())
1771 if glusterfs.found()
1772 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4'))
1773 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5'))
1774 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6'))
1775 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6'))
1776 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat)
1777 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat)
1778 endif
1779 config_host_data.set('CONFIG_GTK', gtk.found())
1780 config_host_data.set('CONFIG_VTE', vte.found())
1781 config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
1782 config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
1783 config_host_data.set('CONFIG_EBPF', libbpf.found())
1784 config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
1785 config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
1786 config_host_data.set('CONFIG_LIBNFS', libnfs.found())
1787 config_host_data.set('CONFIG_LIBSSH', libssh.found())
1788 config_host_data.set('CONFIG_LINUX_AIO', libaio.found())
1789 config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found())
1790 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))
1791 config_host_data.set('CONFIG_LIBPMEM', libpmem.found())
1792 config_host_data.set('CONFIG_NUMA', numa.found())
1793 config_host_data.set('CONFIG_OPENGL', opengl.found())
1794 config_host_data.set('CONFIG_PROFILER', get_option('profiler'))
1795 config_host_data.set('CONFIG_RBD', rbd.found())
1796 config_host_data.set('CONFIG_RDMA', rdma.found())
1797 config_host_data.set('CONFIG_SDL', sdl.found())
1798 config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found())
1799 config_host_data.set('CONFIG_SECCOMP', seccomp.found())
1800 config_host_data.set('CONFIG_SNAPPY', snappy.found())
1801 config_host_data.set('CONFIG_TPM', have_tpm)
1802 config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
1803 config_host_data.set('CONFIG_VDE', vde.found())
1804 config_host_data.set('CONFIG_VHOST_NET', have_vhost_net)
1805 config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user)
1806 config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa)
1807 config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel)
1808 config_host_data.set('CONFIG_VHOST_USER', have_vhost_user)
1809 config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto)
1810 config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa)
1811 config_host_data.set('CONFIG_VMNET', vmnet.found())
1812 config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
1813 config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export)
1814 config_host_data.set('CONFIG_PNG', png.found())
1815 config_host_data.set('CONFIG_VNC', vnc.found())
1816 config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
1817 config_host_data.set('CONFIG_VNC_SASL', sasl.found())
1818 config_host_data.set('CONFIG_VIRTFS', have_virtfs)
1819 config_host_data.set('CONFIG_VTE', vte.found())
1820 config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
1821 config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
1822 config_host_data.set('CONFIG_GETTID', has_gettid)
1823 config_host_data.set('CONFIG_GNUTLS', gnutls.found())
1824 config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found())
1825 config_host_data.set('CONFIG_TASN1', tasn1.found())
1826 config_host_data.set('CONFIG_GCRYPT', gcrypt.found())
1827 config_host_data.set('CONFIG_NETTLE', nettle.found())
1828 config_host_data.set('CONFIG_HOGWEED', hogweed.found())
1829 config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private')
1830 config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim)
1831 config_host_data.set('CONFIG_STATX', has_statx)
1832 config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id)
1833 config_host_data.set('CONFIG_ZSTD', zstd.found())
1834 config_host_data.set('CONFIG_FUSE', fuse.found())
1835 config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found())
1836 config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found())
1837 if spice_protocol.found()
1838 config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0])
1839 config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1])
1840 config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2])
1841 endif
1842 config_host_data.set('CONFIG_SPICE', spice.found())
1843 config_host_data.set('CONFIG_X11', x11.found())
1844 config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display)
1845 config_host_data.set('CONFIG_CFI', get_option('cfi'))
1846 config_host_data.set('CONFIG_SELINUX', selinux.found())
1847 config_host_data.set('CONFIG_XEN_BACKEND', xen.found())
1848 if xen.found()
1849 # protect from xen.version() having less than three components
1850 xen_version = xen.version().split('.') + ['0', '0']
1851 xen_ctrl_version = xen_version[0] + \
1852 ('0' + xen_version[1]).substring(-2) + \
1853 ('0' + xen_version[2]).substring(-2)
1854 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version)
1855 endif
1856 config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
1857 config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
1858 config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
1859 config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2])
1860
1861 config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf)
1862 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
1863
1864 have_coroutine_pool = get_option('coroutine_pool')
1865 if get_option('debug_stack_usage') and have_coroutine_pool
1866 message('Disabling coroutine pool to measure stack usage')
1867 have_coroutine_pool = false
1868 endif
1869 config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool)
1870 config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex'))
1871 config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage'))
1872 config_host_data.set('CONFIG_GPROF', get_option('gprof'))
1873 config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed())
1874 config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug'))
1875 config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed())
1876
1877 # has_header
1878 config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h'))
1879 config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h'))
1880 config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h'))
1881 config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h'))
1882 config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h'))
1883 config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
1884 config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
1885 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
1886 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
1887 if targetos == 'windows'
1888 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h'))
1889 endif
1890
1891 # has_function
1892 config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4'))
1893 config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
1894 config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
1895 config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
1896 config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
1897 # Note that we need to specify prefix: here to avoid incorrectly
1898 # thinking that Windows has posix_memalign()
1899 config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
1900 config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
1901 config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
1902 config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
1903 config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
1904 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
1905 config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np'))
1906 config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile'))
1907 config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare'))
1908 config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs'))
1909 config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range'))
1910 config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create'))
1911 config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range'))
1912 config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs'))
1913 config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util))
1914 config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul'))
1915 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
1916 if rbd.found()
1917 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS',
1918 cc.has_function('rbd_namespace_exists',
1919 dependencies: rbd,
1920 prefix: '#include <rbd/librbd.h>'))
1921 endif
1922 if rdma.found()
1923 config_host_data.set('HAVE_IBV_ADVISE_MR',
1924 cc.has_function('ibv_advise_mr',
1925 dependencies: rdma,
1926 prefix: '#include <infiniband/verbs.h>'))
1927 endif
1928
1929 # has_header_symbol
1930 config_host_data.set('CONFIG_BYTESWAP_H',
1931 cc.has_header_symbol('byteswap.h', 'bswap_32'))
1932 config_host_data.set('CONFIG_EPOLL_CREATE1',
1933 cc.has_header_symbol('sys/epoll.h', 'epoll_create1'))
1934 config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE',
1935 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and
1936 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE'))
1937 config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE',
1938 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE'))
1939 config_host_data.set('CONFIG_FIEMAP',
1940 cc.has_header('linux/fiemap.h') and
1941 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP'))
1942 config_host_data.set('CONFIG_GETRANDOM',
1943 cc.has_function('getrandom') and
1944 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK'))
1945 config_host_data.set('CONFIG_INOTIFY',
1946 cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
1947 config_host_data.set('CONFIG_INOTIFY1',
1948 cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
1949 config_host_data.set('CONFIG_MACHINE_BSWAP_H',
1950 cc.has_header_symbol('machine/bswap.h', 'bswap32',
1951 prefix: '''#include <sys/endian.h>
1952 #include <sys/types.h>'''))
1953 config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK',
1954 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK'))
1955 config_host_data.set('CONFIG_RTNETLINK',
1956 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN'))
1957 config_host_data.set('CONFIG_SYSMACROS',
1958 cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
1959 config_host_data.set('HAVE_OPTRESET',
1960 cc.has_header_symbol('getopt.h', 'optreset'))
1961 config_host_data.set('HAVE_IPPROTO_MPTCP',
1962 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
1963 config_host_data.set('HAVE_SYS_MOUNT_FSCONFIG',
1964 cc.has_header_symbol('sys/mount.h', 'FSCONFIG_SET_FLAG'))
1965
1966 # has_member
1967 config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID',
1968 cc.has_member('struct sigevent', 'sigev_notify_thread_id',
1969 prefix: '#include <signal.h>'))
1970 config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
1971 cc.has_member('struct stat', 'st_atim',
1972 prefix: '#include <sys/stat.h>'))
1973
1974 # has_type
1975 config_host_data.set('CONFIG_IOVEC',
1976 cc.has_type('struct iovec',
1977 prefix: '#include <sys/uio.h>'))
1978 config_host_data.set('HAVE_UTMPX',
1979 cc.has_type('struct utmpx',
1980 prefix: '#include <utmpx.h>'))
1981
1982 config_host_data.set('CONFIG_EVENTFD', cc.links('''
1983 #include <sys/eventfd.h>
1984 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
1985 config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + '''
1986 #include <unistd.h>
1987 int main(void) {
1988 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
1989 return fdatasync(0);
1990 #else
1991 #error Not supported
1992 #endif
1993 }'''))
1994
1995 has_madvise = cc.links(gnu_source_prefix + '''
1996 #include <sys/types.h>
1997 #include <sys/mman.h>
1998 #include <stddef.h>
1999 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')
2000 missing_madvise_proto = false
2001 if has_madvise
2002 # Some platforms (illumos and Solaris before Solaris 11) provide madvise()
2003 # but forget to prototype it. In this case, has_madvise will be true (the
2004 # test program links despite a compile warning). To detect the
2005 # missing-prototype case, we try again with a definitely-bogus prototype.
2006 # This will only compile if the system headers don't provide the prototype;
2007 # otherwise the conflicting prototypes will cause a compiler error.
2008 missing_madvise_proto = cc.links(gnu_source_prefix + '''
2009 #include <sys/types.h>
2010 #include <sys/mman.h>
2011 #include <stddef.h>
2012 extern int madvise(int);
2013 int main(void) { return madvise(0); }''')
2014 endif
2015 config_host_data.set('CONFIG_MADVISE', has_madvise)
2016 config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto)
2017
2018 config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + '''
2019 #include <sys/mman.h>
2020 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }'''))
2021 config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + '''
2022 #include <fcntl.h>
2023 #if !defined(AT_EMPTY_PATH)
2024 # error missing definition
2025 #else
2026 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); }
2027 #endif'''))
2028 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
2029 #include <sys/mman.h>
2030 #include <stddef.h>
2031 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
2032
2033 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
2034 #include <pthread.h>
2035
2036 static void *f(void *p) { return NULL; }
2037 int main(void)
2038 {
2039 pthread_t thread;
2040 pthread_create(&thread, 0, f, 0);
2041 pthread_setname_np(thread, "QEMU");
2042 return 0;
2043 }''', dependencies: threads))
2044 config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
2045 #include <pthread.h>
2046
2047 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
2048 int main(void)
2049 {
2050 pthread_t thread;
2051 pthread_create(&thread, 0, f, 0);
2052 return 0;
2053 }''', dependencies: threads))
2054 config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + '''
2055 #include <pthread.h>
2056 #include <time.h>
2057
2058 int main(void)
2059 {
2060 pthread_condattr_t attr
2061 pthread_condattr_init(&attr);
2062 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
2063 return 0;
2064 }''', dependencies: threads))
2065
2066 config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + '''
2067 #include <sys/signalfd.h>
2068 #include <stddef.h>
2069 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }'''))
2070 config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + '''
2071 #include <unistd.h>
2072 #include <fcntl.h>
2073 #include <limits.h>
2074
2075 int main(void)
2076 {
2077 int len, fd = 0;
2078 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK);
2079 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE);
2080 return 0;
2081 }'''))
2082
2083 config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
2084 #include <sys/mman.h>
2085 int main(int argc, char *argv[]) {
2086 return mlockall(MCL_FUTURE);
2087 }'''))
2088
2089 have_l2tpv3 = false
2090 if get_option('l2tpv3').allowed() and have_system
2091 have_l2tpv3 = cc.has_type('struct mmsghdr',
2092 prefix: gnu_source_prefix + '''
2093 #include <sys/socket.h>
2094 #include <linux/ip.h>''')
2095 endif
2096 config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
2097
2098 have_netmap = false
2099 if get_option('netmap').allowed() and have_system
2100 have_netmap = cc.compiles('''
2101 #include <inttypes.h>
2102 #include <net/if.h>
2103 #include <net/netmap.h>
2104 #include <net/netmap_user.h>
2105 #if (NETMAP_API < 11) || (NETMAP_API > 15)
2106 #error
2107 #endif
2108 int main(void) { return 0; }''')
2109 if not have_netmap and get_option('netmap').enabled()
2110 error('Netmap headers not available')
2111 endif
2112 endif
2113 config_host_data.set('CONFIG_NETMAP', have_netmap)
2114
2115 # Work around a system header bug with some kernel/XFS header
2116 # versions where they both try to define 'struct fsxattr':
2117 # xfs headers will not try to redefine structs from linux headers
2118 # if this macro is set.
2119 config_host_data.set('HAVE_FSXATTR', cc.links('''
2120 #include <linux/fs.h>
2121 struct fsxattr foo;
2122 int main(void) {
2123 return 0;
2124 }'''))
2125
2126 # Some versions of Mac OS X incorrectly define SIZE_MAX
2127 config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles('''
2128 #include <stdint.h>
2129 #include <stdio.h>
2130 int main(int argc, char *argv[]) {
2131 return printf("%zu", SIZE_MAX);
2132 }''', args: ['-Werror']))
2133
2134 atomic_test = '''
2135 #include <stdint.h>
2136 int main(void)
2137 {
2138 @0@ x = 0, y = 0;
2139 y = __atomic_load_n(&x, __ATOMIC_RELAXED);
2140 __atomic_store_n(&x, y, __ATOMIC_RELAXED);
2141 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
2142 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED);
2143 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED);
2144 return 0;
2145 }'''
2146
2147 # See if 64-bit atomic operations are supported.
2148 # Note that without __atomic builtins, we can only
2149 # assume atomic loads/stores max at pointer size.
2150 config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t')))
2151
2152 has_int128 = cc.links('''
2153 __int128_t a;
2154 __uint128_t b;
2155 int main (void) {
2156 a = a + b;
2157 b = a * b;
2158 a = a * a;
2159 return 0;
2160 }''')
2161
2162 config_host_data.set('CONFIG_INT128', has_int128)
2163
2164 if has_int128
2165 # "do we have 128-bit atomics which are handled inline and specifically not
2166 # via libatomic". The reason we can't use libatomic is documented in the
2167 # comment starting "GCC is a house divided" in include/qemu/atomic128.h.
2168 has_atomic128 = cc.links(atomic_test.format('unsigned __int128'))
2169
2170 config_host_data.set('CONFIG_ATOMIC128', has_atomic128)
2171
2172 if not has_atomic128
2173 has_cmpxchg128 = cc.links('''
2174 int main(void)
2175 {
2176 unsigned __int128 x = 0, y = 0;
2177 __sync_val_compare_and_swap_16(&x, y, x);
2178 return 0;
2179 }
2180 ''')
2181
2182 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128)
2183 endif
2184 endif
2185
2186 config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + '''
2187 #include <sys/auxv.h>
2188 int main(void) {
2189 return getauxval(AT_HWCAP) == 0;
2190 }'''))
2191
2192 config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
2193 #include <linux/usbdevice_fs.h>
2194
2195 #ifndef USBDEVFS_GET_CAPABILITIES
2196 #error "USBDEVFS_GET_CAPABILITIES undefined"
2197 #endif
2198
2199 #ifndef USBDEVFS_DISCONNECT_CLAIM
2200 #error "USBDEVFS_DISCONNECT_CLAIM undefined"
2201 #endif
2202
2203 int main(void) { return 0; }'''))
2204
2205 have_keyring = get_option('keyring') \
2206 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \
2207 .require(cc.compiles('''
2208 #include <errno.h>
2209 #include <asm/unistd.h>
2210 #include <linux/keyctl.h>
2211 #include <sys/syscall.h>
2212 #include <unistd.h>
2213 int main(void) {
2214 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0);
2215 }'''), error_message: 'keyctl syscall not available on this system').allowed()
2216 config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring)
2217
2218 have_cpuid_h = cc.links('''
2219 #include <cpuid.h>
2220 int main(void) {
2221 unsigned a, b, c, d;
2222 unsigned max = __get_cpuid_max(0, 0);
2223
2224 if (max >= 1) {
2225 __cpuid(1, a, b, c, d);
2226 }
2227
2228 if (max >= 7) {
2229 __cpuid_count(7, 0, a, b, c, d);
2230 }
2231
2232 return 0;
2233 }''')
2234 config_host_data.set('CONFIG_CPUID_H', have_cpuid_h)
2235
2236 config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \
2237 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \
2238 .require(cc.links('''
2239 #pragma GCC push_options
2240 #pragma GCC target("avx2")
2241 #include <cpuid.h>
2242 #include <immintrin.h>
2243 static int bar(void *a) {
2244 __m256i x = *(__m256i *)a;
2245 return _mm256_testz_si256(x, x);
2246 }
2247 int main(int argc, char *argv[]) { return bar(argv[0]); }
2248 '''), error_message: 'AVX2 not available').allowed())
2249
2250 config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \
2251 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \
2252 .require(cc.links('''
2253 #pragma GCC push_options
2254 #pragma GCC target("avx512f")
2255 #include <cpuid.h>
2256 #include <immintrin.h>
2257 static int bar(void *a) {
2258 __m512i x = *(__m512i *)a;
2259 return _mm512_test_epi64_mask(x, x);
2260 }
2261 int main(int argc, char *argv[]) { return bar(argv[0]); }
2262 '''), error_message: 'AVX512F not available').allowed())
2263
2264 have_pvrdma = get_option('pvrdma') \
2265 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \
2266 .require(cc.compiles(gnu_source_prefix + '''
2267 #include <sys/mman.h>
2268 int main(void)
2269 {
2270 char buf = 0;
2271 void *addr = &buf;
2272 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED);
2273
2274 return 0;
2275 }'''), error_message: 'PVRDMA requires mremap').allowed()
2276
2277 if have_pvrdma
2278 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links('''
2279 #include <infiniband/verbs.h>
2280 int main(void)
2281 {
2282 struct ibv_mr *mr;
2283 struct ibv_pd *pd = NULL;
2284 size_t length = 10;
2285 uint64_t iova = 0;
2286 int access = 0;
2287 void *addr = NULL;
2288
2289 mr = ibv_reg_mr_iova(pd, addr, length, iova, access);
2290 ibv_dereg_mr(mr);
2291 return 0;
2292 }'''))
2293 endif
2294
2295 if get_option('membarrier').disabled()
2296 have_membarrier = false
2297 elif targetos == 'windows'
2298 have_membarrier = true
2299 elif targetos == 'linux'
2300 have_membarrier = cc.compiles('''
2301 #include <linux/membarrier.h>
2302 #include <sys/syscall.h>
2303 #include <unistd.h>
2304 #include <stdlib.h>
2305 int main(void) {
2306 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
2307 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0);
2308 exit(0);
2309 }''')
2310 endif
2311 config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \
2312 .require(have_membarrier, error_message: 'membarrier system call not available') \
2313 .allowed())
2314
2315 have_afalg = get_option('crypto_afalg') \
2316 .require(cc.compiles(gnu_source_prefix + '''
2317 #include <errno.h>
2318 #include <sys/types.h>
2319 #include <sys/socket.h>
2320 #include <linux/if_alg.h>
2321 int main(void) {
2322 int sock;
2323 sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
2324 return sock;
2325 }
2326 '''), error_message: 'AF_ALG requested but could not be detected').allowed()
2327 config_host_data.set('CONFIG_AF_ALG', have_afalg)
2328
2329 config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol(
2330 'linux/vm_sockets.h', 'AF_VSOCK',
2331 prefix: '#include <sys/socket.h>',
2332 ))
2333
2334 have_vss = false
2335 have_vss_sdk = false # old xp/2003 SDK
2336 if targetos == 'windows' and link_language == 'cpp'
2337 have_vss = cxx.compiles('''
2338 #define __MIDL_user_allocate_free_DEFINED__
2339 #include <vss.h>
2340 int main(void) { return VSS_CTX_BACKUP; }''')
2341 have_vss_sdk = cxx.has_header('vscoordint.h')
2342 endif
2343 config_host_data.set('HAVE_VSS_SDK', have_vss_sdk)
2344
2345 foreach k, v: config_host
2346 if k.startswith('CONFIG_')
2347 config_host_data.set(k, v == 'y' ? 1 : v)
2348 endif
2349 endforeach
2350
2351 # Older versions of MinGW do not import _lock_file and _unlock_file properly.
2352 # This was fixed for v6.0.0 with commit b48e3ac8969d.
2353 if targetos == 'windows'
2354 config_host_data.set('HAVE__LOCK_FILE', cc.links('''
2355 #include <stdio.h>
2356 int main(void) {
2357 _lock_file(NULL);
2358 _unlock_file(NULL);
2359 return 0;
2360 }''', name: '_lock_file and _unlock_file'))
2361 endif
2362
2363 ########################
2364 # Target configuration #
2365 ########################
2366
2367 minikconf = find_program('scripts/minikconf.py')
2368 config_all = {}
2369 config_all_devices = {}
2370 config_all_disas = {}
2371 config_devices_mak_list = []
2372 config_devices_h = {}
2373 config_target_h = {}
2374 config_target_mak = {}
2375
2376 disassemblers = {
2377 'alpha' : ['CONFIG_ALPHA_DIS'],
2378 'avr' : ['CONFIG_AVR_DIS'],
2379 'cris' : ['CONFIG_CRIS_DIS'],
2380 'hexagon' : ['CONFIG_HEXAGON_DIS'],
2381 'hppa' : ['CONFIG_HPPA_DIS'],
2382 'i386' : ['CONFIG_I386_DIS'],
2383 'x86_64' : ['CONFIG_I386_DIS'],
2384 'm68k' : ['CONFIG_M68K_DIS'],
2385 'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
2386 'mips' : ['CONFIG_MIPS_DIS'],
2387 'nios2' : ['CONFIG_NIOS2_DIS'],
2388 'or1k' : ['CONFIG_OPENRISC_DIS'],
2389 'ppc' : ['CONFIG_PPC_DIS'],
2390 'riscv' : ['CONFIG_RISCV_DIS'],
2391 'rx' : ['CONFIG_RX_DIS'],
2392 's390' : ['CONFIG_S390_DIS'],
2393 'sh4' : ['CONFIG_SH4_DIS'],
2394 'sparc' : ['CONFIG_SPARC_DIS'],
2395 'xtensa' : ['CONFIG_XTENSA_DIS'],
2396 'loongarch' : ['CONFIG_LOONGARCH_DIS'],
2397 }
2398 if link_language == 'cpp'
2399 disassemblers += {
2400 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
2401 }
2402 endif
2403
2404 have_ivshmem = config_host_data.get('CONFIG_EVENTFD')
2405 host_kconfig = \
2406 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \
2407 (have_tpm ? ['CONFIG_TPM=y'] : []) + \
2408 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \
2409 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \
2410 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \
2411 (x11.found() ? ['CONFIG_X11=y'] : []) + \
2412 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \
2413 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \
2414 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \
2415 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \
2416 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \
2417 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \
2418 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \
2419 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : [])
2420
2421 ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ]
2422
2423 default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host
2424 actual_target_dirs = []
2425 fdt_required = []
2426 foreach target : target_dirs
2427 config_target = { 'TARGET_NAME': target.split('-')[0] }
2428 if target.endswith('linux-user')
2429 if targetos != 'linux'
2430 if default_targets
2431 continue
2432 endif
2433 error('Target @0@ is only available on a Linux host'.format(target))
2434 endif
2435 config_target += { 'CONFIG_LINUX_USER': 'y' }
2436 elif target.endswith('bsd-user')
2437 if 'CONFIG_BSD' not in config_host
2438 if default_targets
2439 continue
2440 endif
2441 error('Target @0@ is only available on a BSD host'.format(target))
2442 endif
2443 config_target += { 'CONFIG_BSD_USER': 'y' }
2444 elif target.endswith('softmmu')
2445 config_target += { 'CONFIG_SOFTMMU': 'y' }
2446 endif
2447 if target.endswith('-user')
2448 config_target += {
2449 'CONFIG_USER_ONLY': 'y',
2450 'CONFIG_QEMU_INTERP_PREFIX':
2451 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME'])
2452 }
2453 endif
2454
2455 accel_kconfig = []
2456 foreach sym: accelerators
2457 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, [])
2458 config_target += { sym: 'y' }
2459 config_all += { sym: 'y' }
2460 if sym == 'CONFIG_TCG' and tcg_arch == 'tci'
2461 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' }
2462 endif
2463 if target in modular_tcg
2464 config_target += { 'CONFIG_TCG_MODULAR': 'y' }
2465 else
2466 config_target += { 'CONFIG_TCG_BUILTIN': 'y' }
2467 endif
2468 accel_kconfig += [ sym + '=y' ]
2469 endif
2470 endforeach
2471 if accel_kconfig.length() == 0
2472 if default_targets
2473 continue
2474 endif
2475 error('No accelerator available for target @0@'.format(target))
2476 endif
2477
2478 actual_target_dirs += target
2479 config_target += keyval.load('configs/targets' / target + '.mak')
2480 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' }
2481
2482 if 'TARGET_NEED_FDT' in config_target
2483 fdt_required += target
2484 endif
2485
2486 # Add default keys
2487 if 'TARGET_BASE_ARCH' not in config_target
2488 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']}
2489 endif
2490 if 'TARGET_ABI_DIR' not in config_target
2491 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']}
2492 endif
2493 if 'TARGET_BIG_ENDIAN' not in config_target
2494 config_target += {'TARGET_BIG_ENDIAN': 'n'}
2495 endif
2496
2497 foreach k, v: disassemblers
2498 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
2499 foreach sym: v
2500 config_target += { sym: 'y' }
2501 config_all_disas += { sym: 'y' }
2502 endforeach
2503 endif
2504 endforeach
2505
2506 config_target_data = configuration_data()
2507 foreach k, v: config_target
2508 if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
2509 # do nothing
2510 elif ignored.contains(k)
2511 # do nothing
2512 elif k == 'TARGET_BASE_ARCH'
2513 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is
2514 # not used to select files from sourcesets.
2515 config_target_data.set('TARGET_' + v.to_upper(), 1)
2516 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX'
2517 config_target_data.set_quoted(k, v)
2518 elif v == 'y'
2519 config_target_data.set(k, 1)
2520 elif v == 'n'
2521 config_target_data.set(k, 0)
2522 else
2523 config_target_data.set(k, v)
2524 endif
2525 endforeach
2526 config_target_data.set('QEMU_ARCH',
2527 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper())
2528 config_target_h += {target: configure_file(output: target + '-config-target.h',
2529 configuration: config_target_data)}
2530
2531 if target.endswith('-softmmu')
2532 config_input = meson.get_external_property(target, 'default')
2533 config_devices_mak = target + '-config-devices.mak'
2534 config_devices_mak = configure_file(
2535 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'],
2536 output: config_devices_mak,
2537 depfile: config_devices_mak + '.d',
2538 capture: true,
2539 command: [minikconf,
2540 get_option('default_devices') ? '--defconfig' : '--allnoconfig',
2541 config_devices_mak, '@DEPFILE@', '@INPUT@',
2542 host_kconfig, accel_kconfig,
2543 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y'])
2544
2545 config_devices_data = configuration_data()
2546 config_devices = keyval.load(config_devices_mak)
2547 foreach k, v: config_devices
2548 config_devices_data.set(k, 1)
2549 endforeach
2550 config_devices_mak_list += config_devices_mak
2551 config_devices_h += {target: configure_file(output: target + '-config-devices.h',
2552 configuration: config_devices_data)}
2553 config_target += config_devices
2554 config_all_devices += config_devices
2555 endif
2556 config_target_mak += {target: config_target}
2557 endforeach
2558 target_dirs = actual_target_dirs
2559
2560 # This configuration is used to build files that are shared by
2561 # multiple binaries, and then extracted out of the "common"
2562 # static_library target.
2563 #
2564 # We do not use all_sources()/all_dependencies(), because it would
2565 # build literally all source files, including devices only used by
2566 # targets that are not built for this compilation. The CONFIG_ALL
2567 # pseudo symbol replaces it.
2568
2569 config_all += config_all_devices
2570 config_all += config_host
2571 config_all += config_all_disas
2572 config_all += {
2573 'CONFIG_XEN': xen.found(),
2574 'CONFIG_SOFTMMU': have_system,
2575 'CONFIG_USER_ONLY': have_user,
2576 'CONFIG_ALL': true,
2577 }
2578
2579 target_configs_h = []
2580 foreach target: target_dirs
2581 target_configs_h += config_target_h[target]
2582 target_configs_h += config_devices_h.get(target, [])
2583 endforeach
2584 genh += custom_target('config-poison.h',
2585 input: [target_configs_h],
2586 output: 'config-poison.h',
2587 capture: true,
2588 command: [find_program('scripts/make-config-poison.sh'),
2589 target_configs_h])
2590
2591 ##############
2592 # Submodules #
2593 ##############
2594
2595 capstone = not_found
2596 if not get_option('capstone').auto() or have_system or have_user
2597 capstone = dependency('capstone', version: '>=3.0.5',
2598 kwargs: static_kwargs, method: 'pkg-config',
2599 required: get_option('capstone'))
2600
2601 # Some versions of capstone have broken pkg-config file
2602 # that reports a wrong -I path, causing the #include to
2603 # fail later. If the system has such a broken version
2604 # do not use it.
2605 if capstone.found() and not cc.compiles('#include <capstone.h>',
2606 dependencies: [capstone])
2607 capstone = not_found
2608 if get_option('capstone').enabled()
2609 error('capstone requested, but it does not appear to work')
2610 endif
2611 endif
2612 endif
2613
2614 slirp = not_found
2615 slirp_opt = 'disabled'
2616 if have_system
2617 slirp_opt = get_option('slirp')
2618 if slirp_opt in ['enabled', 'auto', 'system']
2619 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build')
2620 slirp_dep_required = (slirp_opt == 'system' or
2621 slirp_opt == 'enabled' and not have_internal)
2622 slirp = dependency('slirp', kwargs: static_kwargs,
2623 method: 'pkg-config', version: '>=4.1.0',
2624 required: slirp_dep_required)
2625 # slirp <4.7 is incompatible with CFI support in QEMU. This is because
2626 # it passes function pointers within libslirp as callbacks for timers.
2627 # When using a system-wide shared libslirp, the type information for the
2628 # callback is missing and the timer call produces a false positive with CFI.
2629 # Do not use the "version" keyword argument to produce a better error.
2630 # with control-flow integrity.
2631 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7')
2632 if slirp_dep_required
2633 error('Control-Flow Integrity requires libslirp 4.7.')
2634 else
2635 warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.')
2636 slirp = not_found
2637 endif
2638 endif
2639 if slirp.found()
2640 slirp_opt = 'system'
2641 elif have_internal
2642 slirp_opt = 'internal'
2643 else
2644 slirp_opt = 'disabled'
2645 endif
2646 endif
2647 if slirp_opt == 'internal'
2648 slirp_deps = []
2649 if targetos == 'windows'
2650 slirp_deps = cc.find_library('iphlpapi')
2651 elif targetos == 'darwin'
2652 slirp_deps = cc.find_library('resolv')
2653 endif
2654 slirp_conf = configuration_data()
2655 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
2656 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1])
2657 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2])
2658 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version())
2659 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"']
2660 slirp_files = [
2661 'slirp/src/arp_table.c',
2662 'slirp/src/bootp.c',
2663 'slirp/src/cksum.c',
2664 'slirp/src/dhcpv6.c',
2665 'slirp/src/dnssearch.c',
2666 'slirp/src/if.c',
2667 'slirp/src/ip6_icmp.c',
2668 'slirp/src/ip6_input.c',
2669 'slirp/src/ip6_output.c',
2670 'slirp/src/ip_icmp.c',
2671 'slirp/src/ip_input.c',
2672 'slirp/src/ip_output.c',
2673 'slirp/src/mbuf.c',
2674 'slirp/src/misc.c',
2675 'slirp/src/ncsi.c',
2676 'slirp/src/ndp_table.c',
2677 'slirp/src/sbuf.c',
2678 'slirp/src/slirp.c',
2679 'slirp/src/socket.c',
2680 'slirp/src/state.c',
2681 'slirp/src/stream.c',
2682 'slirp/src/tcp_input.c',
2683 'slirp/src/tcp_output.c',
2684 'slirp/src/tcp_subr.c',
2685 'slirp/src/tcp_timer.c',
2686 'slirp/src/tftp.c',
2687 'slirp/src/udp.c',
2688 'slirp/src/udp6.c',
2689 'slirp/src/util.c',
2690 'slirp/src/version.c',
2691 'slirp/src/vmstate.c',
2692 ]
2693
2694 configure_file(
2695 input : 'slirp/src/libslirp-version.h.in',
2696 output : 'libslirp-version.h',
2697 configuration: slirp_conf)
2698
2699 slirp_inc = include_directories('slirp', 'slirp/src')
2700 libslirp = static_library('slirp',
2701 build_by_default: false,
2702 sources: slirp_files,
2703 c_args: slirp_cargs,
2704 include_directories: slirp_inc)
2705 slirp = declare_dependency(link_with: libslirp,
2706 dependencies: slirp_deps,
2707 include_directories: slirp_inc)
2708 endif
2709 endif
2710
2711 libvfio_user_dep = not_found
2712 if have_system and vfio_user_server_allowed
2713 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build')
2714
2715 if not have_internal
2716 error('libvfio-user source not found - please pull git submodule')
2717 endif
2718
2719 libvfio_user_proj = subproject('libvfio-user')
2720
2721 libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep')
2722
2723 libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib])
2724 endif
2725
2726 fdt = not_found
2727 if have_system
2728 fdt_opt = get_option('fdt')
2729 if fdt_opt in ['enabled', 'auto', 'system']
2730 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt')
2731 fdt = cc.find_library('fdt', kwargs: static_kwargs,
2732 required: fdt_opt == 'system' or
2733 fdt_opt == 'enabled' and not have_internal)
2734 if fdt.found() and cc.links('''
2735 #include <libfdt.h>
2736 #include <libfdt_env.h>
2737 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''',
2738 dependencies: fdt)
2739 fdt_opt = 'system'
2740 elif fdt_opt == 'system'
2741 error('system libfdt requested, but it is too old (1.5.1 or newer required)')
2742 elif have_internal
2743 fdt_opt = 'internal'
2744 else
2745 fdt_opt = 'disabled'
2746 fdt = not_found
2747 endif
2748 endif
2749 if fdt_opt == 'internal'
2750 fdt_files = files(
2751 'dtc/libfdt/fdt.c',
2752 'dtc/libfdt/fdt_ro.c',
2753 'dtc/libfdt/fdt_wip.c',
2754 'dtc/libfdt/fdt_sw.c',
2755 'dtc/libfdt/fdt_rw.c',
2756 'dtc/libfdt/fdt_strerror.c',
2757 'dtc/libfdt/fdt_empty_tree.c',
2758 'dtc/libfdt/fdt_addresses.c',
2759 'dtc/libfdt/fdt_overlay.c',
2760 'dtc/libfdt/fdt_check.c',
2761 )
2762
2763 fdt_inc = include_directories('dtc/libfdt')
2764 libfdt = static_library('fdt',
2765 build_by_default: false,
2766 sources: fdt_files,
2767 include_directories: fdt_inc)
2768 fdt = declare_dependency(link_with: libfdt,
2769 include_directories: fdt_inc)
2770 endif
2771 else
2772 fdt_opt = 'disabled'
2773 endif
2774 if not fdt.found() and fdt_required.length() > 0
2775 error('fdt not available but required by targets ' + ', '.join(fdt_required))
2776 endif
2777
2778 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
2779 config_host_data.set('CONFIG_FDT', fdt.found())
2780 config_host_data.set('CONFIG_SLIRP', slirp.found())
2781
2782 #####################
2783 # Generated sources #
2784 #####################
2785
2786 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
2787
2788 hxtool = find_program('scripts/hxtool')
2789 shaderinclude = find_program('scripts/shaderinclude.pl')
2790 qapi_gen = find_program('scripts/qapi-gen.py')
2791 qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py',
2792 meson.current_source_dir() / 'scripts/qapi/commands.py',
2793 meson.current_source_dir() / 'scripts/qapi/common.py',
2794 meson.current_source_dir() / 'scripts/qapi/error.py',
2795 meson.current_source_dir() / 'scripts/qapi/events.py',
2796 meson.current_source_dir() / 'scripts/qapi/expr.py',
2797 meson.current_source_dir() / 'scripts/qapi/gen.py',
2798 meson.current_source_dir() / 'scripts/qapi/introspect.py',
2799 meson.current_source_dir() / 'scripts/qapi/parser.py',
2800 meson.current_source_dir() / 'scripts/qapi/schema.py',
2801 meson.current_source_dir() / 'scripts/qapi/source.py',
2802 meson.current_source_dir() / 'scripts/qapi/types.py',
2803 meson.current_source_dir() / 'scripts/qapi/visit.py',
2804 meson.current_source_dir() / 'scripts/qapi/common.py',
2805 meson.current_source_dir() / 'scripts/qapi-gen.py'
2806 ]
2807
2808 tracetool = [
2809 python, files('scripts/tracetool.py'),
2810 '--backend=' + ','.join(get_option('trace_backends'))
2811 ]
2812 tracetool_depends = files(
2813 'scripts/tracetool/backend/log.py',
2814 'scripts/tracetool/backend/__init__.py',
2815 'scripts/tracetool/backend/dtrace.py',
2816 'scripts/tracetool/backend/ftrace.py',
2817 'scripts/tracetool/backend/simple.py',
2818 'scripts/tracetool/backend/syslog.py',
2819 'scripts/tracetool/backend/ust.py',
2820 'scripts/tracetool/format/ust_events_c.py',
2821 'scripts/tracetool/format/ust_events_h.py',
2822 'scripts/tracetool/format/__init__.py',
2823 'scripts/tracetool/format/d.py',
2824 'scripts/tracetool/format/simpletrace_stap.py',
2825 'scripts/tracetool/format/c.py',
2826 'scripts/tracetool/format/h.py',
2827 'scripts/tracetool/format/log_stap.py',
2828 'scripts/tracetool/format/stap.py',
2829 'scripts/tracetool/__init__.py',
2830 'scripts/tracetool/transform.py',
2831 'scripts/tracetool/vcpu.py'
2832 )
2833
2834 qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
2835 meson.current_source_dir(),
2836 get_option('pkgversion'), meson.project_version()]
2837 qemu_version = custom_target('qemu-version.h',
2838 output: 'qemu-version.h',
2839 command: qemu_version_cmd,
2840 capture: true,
2841 build_by_default: true,
2842 build_always_stale: true)
2843 genh += qemu_version
2844
2845 hxdep = []
2846 hx_headers = [
2847 ['qemu-options.hx', 'qemu-options.def'],
2848 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'],
2849 ]
2850 if have_system
2851 hx_headers += [
2852 ['hmp-commands.hx', 'hmp-commands.h'],
2853 ['hmp-commands-info.hx', 'hmp-commands-info.h'],
2854 ]
2855 endif
2856 foreach d : hx_headers
2857 hxdep += custom_target(d[1],
2858 input: files(d[0]),
2859 output: d[1],
2860 capture: true,
2861 build_by_default: true, # to be removed when added to a target
2862 command: [hxtool, '-h', '@INPUT0@'])
2863 endforeach
2864 genh += hxdep
2865
2866 ###################
2867 # Collect sources #
2868 ###################
2869
2870 authz_ss = ss.source_set()
2871 blockdev_ss = ss.source_set()
2872 block_ss = ss.source_set()
2873 chardev_ss = ss.source_set()
2874 common_ss = ss.source_set()
2875 crypto_ss = ss.source_set()
2876 hwcore_ss = ss.source_set()
2877 io_ss = ss.source_set()
2878 qmp_ss = ss.source_set()
2879 qom_ss = ss.source_set()
2880 softmmu_ss = ss.source_set()
2881 specific_fuzz_ss = ss.source_set()
2882 specific_ss = ss.source_set()
2883 stub_ss = ss.source_set()
2884 trace_ss = ss.source_set()
2885 user_ss = ss.source_set()
2886 util_ss = ss.source_set()
2887
2888 # accel modules
2889 qtest_module_ss = ss.source_set()
2890 tcg_module_ss = ss.source_set()
2891
2892 modules = {}
2893 target_modules = {}
2894 hw_arch = {}
2895 target_arch = {}
2896 target_softmmu_arch = {}
2897 target_user_arch = {}
2898
2899 ###############
2900 # Trace files #
2901 ###############
2902
2903 # TODO: add each directory to the subdirs from its own meson.build, once
2904 # we have those
2905 trace_events_subdirs = [
2906 'crypto',
2907 'qapi',
2908 'qom',
2909 'monitor',
2910 'util',
2911 ]
2912 if have_linux_user
2913 trace_events_subdirs += [ 'linux-user' ]
2914 endif
2915 if have_bsd_user
2916 trace_events_subdirs += [ 'bsd-user' ]
2917 endif
2918 if have_block
2919 trace_events_subdirs += [
2920 'authz',
2921 'block',
2922 'io',
2923 'nbd',
2924 'scsi',
2925 ]
2926 endif
2927 if have_system
2928 trace_events_subdirs += [
2929 'accel/kvm',
2930 'audio',
2931 'backends',
2932 'backends/tpm',
2933 'chardev',
2934 'ebpf',
2935 'hw/9pfs',
2936 'hw/acpi',
2937 'hw/adc',
2938 'hw/alpha',
2939 'hw/arm',
2940 'hw/audio',
2941 'hw/block',
2942 'hw/block/dataplane',
2943 'hw/char',
2944 'hw/display',
2945 'hw/dma',
2946 'hw/hyperv',
2947 'hw/i2c',
2948 'hw/i386',
2949 'hw/i386/xen',
2950 'hw/ide',
2951 'hw/input',
2952 'hw/intc',
2953 'hw/isa',
2954 'hw/mem',
2955 'hw/mips',
2956 'hw/misc',
2957 'hw/misc/macio',
2958 'hw/net',
2959 'hw/net/can',
2960 'hw/nubus',
2961 'hw/nvme',
2962 'hw/nvram',
2963 'hw/pci',
2964 'hw/pci-host',
2965 'hw/ppc',
2966 'hw/rdma',
2967 'hw/rdma/vmw',
2968 'hw/rtc',
2969 'hw/s390x',
2970 'hw/scsi',
2971 'hw/sd',
2972 'hw/sh4',
2973 'hw/sparc',
2974 'hw/sparc64',
2975 'hw/ssi',
2976 'hw/timer',
2977 'hw/tpm',
2978 'hw/usb',
2979 'hw/vfio',
2980 'hw/virtio',
2981 'hw/watchdog',
2982 'hw/xen',
2983 'hw/gpio',
2984 'migration',
2985 'net',
2986 'softmmu',
2987 'ui',
2988 'hw/remote',
2989 ]
2990 endif
2991 if have_system or have_user
2992 trace_events_subdirs += [
2993 'accel/tcg',
2994 'hw/core',
2995 'target/arm',
2996 'target/arm/hvf',
2997 'target/hppa',
2998 'target/i386',
2999 'target/i386/kvm',
3000 'target/mips/tcg',
3001 'target/nios2',
3002 'target/ppc',
3003 'target/riscv',
3004 'target/s390x',
3005 'target/s390x/kvm',
3006 'target/sparc',
3007 ]
3008 endif
3009
3010 vhost_user = not_found
3011 if targetos == 'linux' and have_vhost_user
3012 libvhost_user = subproject('libvhost-user')
3013 vhost_user = libvhost_user.get_variable('vhost_user_dep')
3014 endif
3015
3016 libvduse = not_found
3017 if have_libvduse
3018 libvduse_proj = subproject('libvduse')
3019 libvduse = libvduse_proj.get_variable('libvduse_dep')
3020 endif
3021
3022 # NOTE: the trace/ subdirectory needs the qapi_trace_events variable
3023 # that is filled in by qapi/.
3024 subdir('qapi')
3025 subdir('qobject')
3026 subdir('stubs')
3027 subdir('trace')
3028 subdir('util')
3029 subdir('qom')
3030 subdir('authz')
3031 subdir('crypto')
3032 subdir('ui')
3033 subdir('hw')
3034
3035
3036 if enable_modules
3037 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
3038 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
3039 endif
3040
3041 qom_ss = qom_ss.apply(config_host, strict: false)
3042 libqom = static_library('qom', qom_ss.sources() + genh,
3043 dependencies: [qom_ss.dependencies()],
3044 name_suffix: 'fa')
3045 qom = declare_dependency(link_whole: libqom)
3046
3047 event_loop_base = files('event-loop-base.c')
3048 event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
3049 build_by_default: true)
3050 event_loop_base = declare_dependency(link_whole: event_loop_base,
3051 dependencies: [qom])
3052
3053 stub_ss = stub_ss.apply(config_all, strict: false)
3054
3055 util_ss.add_all(trace_ss)
3056 util_ss = util_ss.apply(config_all, strict: false)
3057 libqemuutil = static_library('qemuutil',
3058 sources: util_ss.sources() + stub_ss.sources() + genh,
3059 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
3060 qemuutil = declare_dependency(link_with: libqemuutil,
3061 sources: genh + version_res,
3062 dependencies: [event_loop_base])
3063
3064 if have_system or have_user
3065 decodetree = generator(find_program('scripts/decodetree.py'),
3066 output: 'decode-@BASENAME@.c.inc',
3067 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@'])
3068 subdir('libdecnumber')
3069 subdir('target')
3070 endif
3071
3072 subdir('audio')
3073 subdir('io')
3074 subdir('chardev')
3075 subdir('fsdev')
3076 subdir('dump')
3077
3078 if have_block
3079 block_ss.add(files(
3080 'block.c',
3081 'blockjob.c',
3082 'job.c',
3083 'qemu-io-cmds.c',
3084 ))
3085 if config_host_data.get('CONFIG_REPLICATION')
3086 block_ss.add(files('replication.c'))
3087 endif
3088
3089 subdir('nbd')
3090 subdir('scsi')
3091 subdir('block')
3092
3093 blockdev_ss.add(files(
3094 'blockdev.c',
3095 'blockdev-nbd.c',
3096 'iothread.c',
3097 'job-qmp.c',
3098 ), gnutls)
3099
3100 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon,
3101 # os-win32.c does not
3102 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c'))
3103 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')])
3104 endif
3105
3106 common_ss.add(files('cpus-common.c'))
3107
3108 subdir('softmmu')
3109
3110 common_ss.add(capstone)
3111 specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone)
3112
3113 # Work around a gcc bug/misfeature wherein constant propagation looks
3114 # through an alias:
3115 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696
3116 # to guess that a const variable is always zero. Without lto, this is
3117 # impossible, as the alias is restricted to page-vary-common.c. Indeed,
3118 # without lto, not even the alias is required -- we simply use different
3119 # declarations in different compilation units.
3120 pagevary = files('page-vary-common.c')
3121 if get_option('b_lto')
3122 pagevary_flags = ['-fno-lto']
3123 if get_option('cfi')
3124 pagevary_flags += '-fno-sanitize=cfi-icall'
3125 endif
3126 pagevary = static_library('page-vary-common', sources: pagevary + genh,
3127 c_args: pagevary_flags)
3128 pagevary = declare_dependency(link_with: pagevary)
3129 endif
3130 common_ss.add(pagevary)
3131 specific_ss.add(files('page-vary.c'))
3132
3133 subdir('backends')
3134 subdir('disas')
3135 subdir('migration')
3136 subdir('monitor')
3137 subdir('net')
3138 subdir('replay')
3139 subdir('semihosting')
3140 subdir('tcg')
3141 subdir('fpu')
3142 subdir('accel')
3143 subdir('plugins')
3144 subdir('ebpf')
3145
3146 common_user_inc = []
3147
3148 subdir('common-user')
3149 subdir('bsd-user')
3150 subdir('linux-user')
3151
3152 # needed for fuzzing binaries
3153 subdir('tests/qtest/libqos')
3154 subdir('tests/qtest/fuzz')
3155
3156 # accel modules
3157 tcg_real_module_ss = ss.source_set()
3158 tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss)
3159 specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss)
3160 target_modules += { 'accel' : { 'qtest': qtest_module_ss,
3161 'tcg': tcg_real_module_ss }}
3162
3163 ########################
3164 # Library dependencies #
3165 ########################
3166
3167 modinfo_collect = find_program('scripts/modinfo-collect.py')
3168 modinfo_generate = find_program('scripts/modinfo-generate.py')
3169 modinfo_files = []
3170
3171 block_mods = []
3172 softmmu_mods = []
3173 foreach d, list : modules
3174 foreach m, module_ss : list
3175 if enable_modules and targetos != 'windows'
3176 module_ss = module_ss.apply(config_all, strict: false)
3177 sl = static_library(d + '-' + m, [genh, module_ss.sources()],
3178 dependencies: [modulecommon, module_ss.dependencies()], pic: true)
3179 if d == 'block'
3180 block_mods += sl
3181 else
3182 softmmu_mods += sl
3183 endif
3184 if module_ss.sources() != []
3185 # FIXME: Should use sl.extract_all_objects(recursive: true) as
3186 # input. Sources can be used multiple times but objects are
3187 # unique when it comes to lookup in compile_commands.json.
3188 # Depnds on a mesion version with
3189 # https://github.com/mesonbuild/meson/pull/8900
3190 modinfo_files += custom_target(d + '-' + m + '.modinfo',
3191 output: d + '-' + m + '.modinfo',
3192 input: module_ss.sources() + genh,
3193 capture: true,
3194 command: [modinfo_collect, module_ss.sources()])
3195 endif
3196 else
3197 if d == 'block'
3198 block_ss.add_all(module_ss)
3199 else
3200 softmmu_ss.add_all(module_ss)
3201 endif
3202 endif
3203 endforeach
3204 endforeach
3205
3206 foreach d, list : target_modules
3207 foreach m, module_ss : list
3208 if enable_modules and targetos != 'windows'
3209 foreach target : target_dirs
3210 if target.endswith('-softmmu')
3211 config_target = config_target_mak[target]
3212 config_target += config_host
3213 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3214 c_args = ['-DNEED_CPU_H',
3215 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3216 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3217 target_module_ss = module_ss.apply(config_target, strict: false)
3218 if target_module_ss.sources() != []
3219 module_name = d + '-' + m + '-' + config_target['TARGET_NAME']
3220 sl = static_library(module_name,
3221 [genh, target_module_ss.sources()],
3222 dependencies: [modulecommon, target_module_ss.dependencies()],
3223 include_directories: target_inc,
3224 c_args: c_args,
3225 pic: true)
3226 softmmu_mods += sl
3227 # FIXME: Should use sl.extract_all_objects(recursive: true) too.
3228 modinfo_files += custom_target(module_name + '.modinfo',
3229 output: module_name + '.modinfo',
3230 input: target_module_ss.sources() + genh,
3231 capture: true,
3232 command: [modinfo_collect, '--target', target, target_module_ss.sources()])
3233 endif
3234 endif
3235 endforeach
3236 else
3237 specific_ss.add_all(module_ss)
3238 endif
3239 endforeach
3240 endforeach
3241
3242 if enable_modules
3243 foreach target : target_dirs
3244 if target.endswith('-softmmu')
3245 config_target = config_target_mak[target]
3246 config_devices_mak = target + '-config-devices.mak'
3247 modinfo_src = custom_target('modinfo-' + target + '.c',
3248 output: 'modinfo-' + target + '.c',
3249 input: modinfo_files,
3250 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'],
3251 capture: true)
3252
3253 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
3254 modinfo_dep = declare_dependency(link_with: modinfo_lib)
3255
3256 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH']
3257 hw_arch[arch].add(modinfo_dep)
3258 endif
3259 endforeach
3260 endif
3261
3262 nm = find_program('nm')
3263 undefsym = find_program('scripts/undefsym.py')
3264 block_syms = custom_target('block.syms', output: 'block.syms',
3265 input: [libqemuutil, block_mods],
3266 capture: true,
3267 command: [undefsym, nm, '@INPUT@'])
3268 qemu_syms = custom_target('qemu.syms', output: 'qemu.syms',
3269 input: [libqemuutil, softmmu_mods],
3270 capture: true,
3271 command: [undefsym, nm, '@INPUT@'])
3272
3273 authz_ss = authz_ss.apply(config_host, strict: false)
3274 libauthz = static_library('authz', authz_ss.sources() + genh,
3275 dependencies: [authz_ss.dependencies()],
3276 name_suffix: 'fa',
3277 build_by_default: false)
3278
3279 authz = declare_dependency(link_whole: libauthz,
3280 dependencies: qom)
3281
3282 crypto_ss = crypto_ss.apply(config_host, strict: false)
3283 libcrypto = static_library('crypto', crypto_ss.sources() + genh,
3284 dependencies: [crypto_ss.dependencies()],
3285 name_suffix: 'fa',
3286 build_by_default: false)
3287
3288 crypto = declare_dependency(link_whole: libcrypto,
3289 dependencies: [authz, qom])
3290
3291 io_ss = io_ss.apply(config_host, strict: false)
3292 libio = static_library('io', io_ss.sources() + genh,
3293 dependencies: [io_ss.dependencies()],
3294 link_with: libqemuutil,
3295 name_suffix: 'fa',
3296 build_by_default: false)
3297
3298 io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
3299
3300 libmigration = static_library('migration', sources: migration_files + genh,
3301 name_suffix: 'fa',
3302 build_by_default: false)
3303 migration = declare_dependency(link_with: libmigration,
3304 dependencies: [zlib, qom, io])
3305 softmmu_ss.add(migration)
3306
3307 block_ss = block_ss.apply(config_host, strict: false)
3308 libblock = static_library('block', block_ss.sources() + genh,
3309 dependencies: block_ss.dependencies(),
3310 link_depends: block_syms,
3311 name_suffix: 'fa',
3312 build_by_default: false)
3313
3314 block = declare_dependency(link_whole: [libblock],
3315 link_args: '@block.syms',
3316 dependencies: [crypto, io])
3317
3318 blockdev_ss = blockdev_ss.apply(config_host, strict: false)
3319 libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
3320 dependencies: blockdev_ss.dependencies(),
3321 name_suffix: 'fa',
3322 build_by_default: false)
3323
3324 blockdev = declare_dependency(link_whole: [libblockdev],
3325 dependencies: [block, event_loop_base])
3326
3327 qmp_ss = qmp_ss.apply(config_host, strict: false)
3328 libqmp = static_library('qmp', qmp_ss.sources() + genh,
3329 dependencies: qmp_ss.dependencies(),
3330 name_suffix: 'fa',
3331 build_by_default: false)
3332
3333 qmp = declare_dependency(link_whole: [libqmp])
3334
3335 libchardev = static_library('chardev', chardev_ss.sources() + genh,
3336 name_suffix: 'fa',
3337 dependencies: chardev_ss.dependencies(),
3338 build_by_default: false)
3339
3340 chardev = declare_dependency(link_whole: libchardev)
3341
3342 hwcore_ss = hwcore_ss.apply(config_host, strict: false)
3343 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
3344 name_suffix: 'fa',
3345 build_by_default: false)
3346 hwcore = declare_dependency(link_whole: libhwcore)
3347 common_ss.add(hwcore)
3348
3349 ###########
3350 # Targets #
3351 ###########
3352
3353 emulator_modules = []
3354 foreach m : block_mods + softmmu_mods
3355 emulator_modules += shared_module(m.name(),
3356 build_by_default: true,
3357 name_prefix: '',
3358 link_whole: m,
3359 install: true,
3360 install_dir: qemu_moddir)
3361 endforeach
3362 if emulator_modules.length() > 0
3363 alias_target('modules', emulator_modules)
3364 endif
3365
3366 softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp)
3367 common_ss.add(qom, qemuutil)
3368
3369 common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss])
3370 common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss)
3371
3372 common_all = common_ss.apply(config_all, strict: false)
3373 common_all = static_library('common',
3374 build_by_default: false,
3375 sources: common_all.sources() + genh,
3376 include_directories: common_user_inc,
3377 implicit_include_directories: false,
3378 dependencies: common_all.dependencies(),
3379 name_suffix: 'fa')
3380
3381 feature_to_c = find_program('scripts/feature_to_c.sh')
3382
3383 if targetos == 'darwin'
3384 entitlement = find_program('scripts/entitlement.sh')
3385 endif
3386
3387 emulators = {}
3388 foreach target : target_dirs
3389 config_target = config_target_mak[target]
3390 target_name = config_target['TARGET_NAME']
3391 target_base_arch = config_target['TARGET_BASE_ARCH']
3392 arch_srcs = [config_target_h[target]]
3393 arch_deps = []
3394 c_args = ['-DNEED_CPU_H',
3395 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target),
3396 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)]
3397 link_args = emulator_link_args
3398
3399 config_target += config_host
3400 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])]
3401 if targetos == 'linux'
3402 target_inc += include_directories('linux-headers', is_system: true)
3403 endif
3404 if target.endswith('-softmmu')
3405 target_type='system'
3406 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false)
3407 arch_srcs += t.sources()
3408 arch_deps += t.dependencies()
3409
3410 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch
3411 hw = hw_arch[hw_dir].apply(config_target, strict: false)
3412 arch_srcs += hw.sources()
3413 arch_deps += hw.dependencies()
3414
3415 arch_srcs += config_devices_h[target]
3416 link_args += ['@block.syms', '@qemu.syms']
3417 else
3418 abi = config_target['TARGET_ABI_DIR']
3419 target_type='user'
3420 target_inc += common_user_inc
3421 if target_base_arch in target_user_arch
3422 t = target_user_arch[target_base_arch].apply(config_target, strict: false)
3423 arch_srcs += t.sources()
3424 arch_deps += t.dependencies()
3425 endif
3426 if 'CONFIG_LINUX_USER' in config_target
3427 base_dir = 'linux-user'
3428 endif
3429 if 'CONFIG_BSD_USER' in config_target
3430 base_dir = 'bsd-user'
3431 target_inc += include_directories('bsd-user/' / targetos)
3432 target_inc += include_directories('bsd-user/host/' / host_arch)
3433 dir = base_dir / abi
3434 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c')
3435 endif
3436 target_inc += include_directories(
3437 base_dir,
3438 base_dir / abi,
3439 )
3440 if 'CONFIG_LINUX_USER' in config_target
3441 dir = base_dir / abi
3442 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
3443 if config_target.has_key('TARGET_SYSTBL_ABI')
3444 arch_srcs += \
3445 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
3446 extra_args : config_target['TARGET_SYSTBL_ABI'])
3447 endif
3448 endif
3449 endif
3450
3451 if 'TARGET_XML_FILES' in config_target
3452 gdbstub_xml = custom_target(target + '-gdbstub-xml.c',
3453 output: target + '-gdbstub-xml.c',
3454 input: files(config_target['TARGET_XML_FILES'].split()),
3455 command: [feature_to_c, '@INPUT@'],
3456 capture: true)
3457 arch_srcs += gdbstub_xml
3458 endif
3459
3460 t = target_arch[target_base_arch].apply(config_target, strict: false)
3461 arch_srcs += t.sources()
3462 arch_deps += t.dependencies()
3463
3464 target_common = common_ss.apply(config_target, strict: false)
3465 objects = common_all.extract_objects(target_common.sources())
3466 deps = target_common.dependencies()
3467
3468 target_specific = specific_ss.apply(config_target, strict: false)
3469 arch_srcs += target_specific.sources()
3470 arch_deps += target_specific.dependencies()
3471
3472 lib = static_library('qemu-' + target,
3473 sources: arch_srcs + genh,
3474 dependencies: arch_deps,
3475 objects: objects,
3476 include_directories: target_inc,
3477 c_args: c_args,
3478 build_by_default: false,
3479 name_suffix: 'fa')
3480
3481 if target.endswith('-softmmu')
3482 execs = [{
3483 'name': 'qemu-system-' + target_name,
3484 'win_subsystem': 'console',
3485 'sources': files('softmmu/main.c'),
3486 'dependencies': []
3487 }]
3488 if targetos == 'windows' and (sdl.found() or gtk.found())
3489 execs += [{
3490 'name': 'qemu-system-' + target_name + 'w',
3491 'win_subsystem': 'windows',
3492 'sources': files('softmmu/main.c'),
3493 'dependencies': []
3494 }]
3495 endif
3496 if get_option('fuzzing')
3497 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false)
3498 execs += [{
3499 'name': 'qemu-fuzz-' + target_name,
3500 'win_subsystem': 'console',
3501 'sources': specific_fuzz.sources(),
3502 'dependencies': specific_fuzz.dependencies(),
3503 }]
3504 endif
3505 else
3506 execs = [{
3507 'name': 'qemu-' + target_name,
3508 'win_subsystem': 'console',
3509 'sources': [],
3510 'dependencies': []
3511 }]
3512 endif
3513 foreach exe: execs
3514 exe_name = exe['name']
3515 if targetos == 'darwin'
3516 exe_name += '-unsigned'
3517 endif
3518
3519 emulator = executable(exe_name, exe['sources'],
3520 install: true,
3521 c_args: c_args,
3522 dependencies: arch_deps + deps + exe['dependencies'],
3523 objects: lib.extract_all_objects(recursive: true),
3524 link_language: link_language,
3525 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []),
3526 link_args: link_args,
3527 win_subsystem: exe['win_subsystem'])
3528
3529 if targetos == 'darwin'
3530 icon = 'pc-bios/qemu.rsrc'
3531 build_input = [emulator, files(icon)]
3532 install_input = [
3533 get_option('bindir') / exe_name,
3534 meson.current_source_dir() / icon
3535 ]
3536 if 'CONFIG_HVF' in config_target
3537 entitlements = 'accel/hvf/entitlements.plist'
3538 build_input += files(entitlements)
3539 install_input += meson.current_source_dir() / entitlements
3540 endif
3541
3542 emulators += {exe['name'] : custom_target(exe['name'],
3543 input: build_input,
3544 output: exe['name'],
3545 command: [entitlement, '@OUTPUT@', '@INPUT@'])
3546 }
3547
3548 meson.add_install_script(entitlement, '--install',
3549 get_option('bindir') / exe['name'],
3550 install_input)
3551 else
3552 emulators += {exe['name']: emulator}
3553 endif
3554
3555 if stap.found()
3556 foreach stp: [
3557 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false},
3558 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true},
3559 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true},
3560 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true},
3561 ]
3562 custom_target(exe['name'] + stp['ext'],
3563 input: trace_events_all,
3564 output: exe['name'] + stp['ext'],
3565 install: stp['install'],
3566 install_dir: get_option('datadir') / 'systemtap/tapset',
3567 command: [
3568 tracetool, '--group=all', '--format=' + stp['fmt'],
3569 '--binary=' + stp['bin'],
3570 '--target-name=' + target_name,
3571 '--target-type=' + target_type,
3572 '--probe-prefix=qemu.' + target_type + '.' + target_name,
3573 '@INPUT@', '@OUTPUT@'
3574 ],
3575 depend_files: tracetool_depends)
3576 endforeach
3577 endif
3578 endforeach
3579 endforeach
3580
3581 # Other build targets
3582
3583 if 'CONFIG_PLUGIN' in config_host
3584 install_headers('include/qemu/qemu-plugin.h')
3585 endif
3586
3587 subdir('qga')
3588
3589 # Don't build qemu-keymap if xkbcommon is not explicitly enabled
3590 # when we don't build tools or system
3591 if xkbcommon.found()
3592 # used for the update-keymaps target, so include rules even if !have_tools
3593 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh,
3594 dependencies: [qemuutil, xkbcommon], install: have_tools)
3595 endif
3596
3597 if have_tools
3598 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep],
3599 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true)
3600 qemu_io = executable('qemu-io', files('qemu-io.c'),
3601 dependencies: [block, qemuutil], install: true)
3602 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
3603 dependencies: [blockdev, qemuutil, gnutls, selinux],
3604 install: true)
3605
3606 subdir('storage-daemon')
3607 subdir('contrib/rdmacm-mux')
3608 subdir('contrib/elf2dmp')
3609
3610 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'),
3611 dependencies: qemuutil,
3612 install: true)
3613
3614 if have_vhost_user
3615 subdir('contrib/vhost-user-blk')
3616 subdir('contrib/vhost-user-gpu')
3617 subdir('contrib/vhost-user-input')
3618 subdir('contrib/vhost-user-scsi')
3619 endif
3620
3621 if targetos == 'linux'
3622 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'),
3623 dependencies: [qemuutil, libcap_ng],
3624 install: true,
3625 install_dir: get_option('libexecdir'))
3626
3627 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'),
3628 dependencies: [authz, crypto, io, qom, qemuutil,
3629 libcap_ng, mpathpersist],
3630 install: true)
3631 endif
3632
3633 if have_ivshmem
3634 subdir('contrib/ivshmem-client')
3635 subdir('contrib/ivshmem-server')
3636 endif
3637 endif
3638
3639 subdir('scripts')
3640 subdir('tools')
3641 subdir('pc-bios')
3642 subdir('docs')
3643 subdir('tests')
3644 if gtk.found()
3645 subdir('po')
3646 endif
3647
3648 if host_machine.system() == 'windows'
3649 nsis_cmd = [
3650 find_program('scripts/nsis.py'),
3651 '@OUTPUT@',
3652 get_option('prefix'),
3653 meson.current_source_dir(),
3654 host_machine.cpu(),
3655 '--',
3656 '-DDISPLAYVERSION=' + meson.project_version(),
3657 ]
3658 if build_docs
3659 nsis_cmd += '-DCONFIG_DOCUMENTATION=y'
3660 endif
3661 if gtk.found()
3662 nsis_cmd += '-DCONFIG_GTK=y'
3663 endif
3664
3665 nsis = custom_target('nsis',
3666 output: 'qemu-setup-' + meson.project_version() + '.exe',
3667 input: files('qemu.nsi'),
3668 build_always_stale: true,
3669 command: nsis_cmd + ['@INPUT@'])
3670 alias_target('installer', nsis)
3671 endif
3672
3673 #########################
3674 # Configuration summary #
3675 #########################
3676
3677 # Directories
3678 summary_info = {}
3679 summary_info += {'Install prefix': get_option('prefix')}
3680 summary_info += {'BIOS directory': qemu_datadir}
3681 pathsep = targetos == 'windows' ? ';' : ':'
3682 summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))}
3683 summary_info += {'binary directory': get_option('prefix') / get_option('bindir')}
3684 summary_info += {'library directory': get_option('prefix') / get_option('libdir')}
3685 summary_info += {'module directory': qemu_moddir}
3686 summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')}
3687 summary_info += {'include directory': get_option('prefix') / get_option('includedir')}
3688 summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')}
3689 if targetos != 'windows'
3690 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')}
3691 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')}
3692 else
3693 summary_info += {'local state directory': 'queried at runtime'}
3694 endif
3695 summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')}
3696 summary_info += {'Build directory': meson.current_build_dir()}
3697 summary_info += {'Source path': meson.current_source_dir()}
3698 summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']}
3699 summary(summary_info, bool_yn: true, section: 'Directories')
3700
3701 # Host binaries
3702 summary_info = {}
3703 summary_info += {'git': config_host['GIT']}
3704 summary_info += {'make': config_host['MAKE']}
3705 summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
3706 summary_info += {'sphinx-build': sphinx_build}
3707 if config_host.has_key('HAVE_GDB_BIN')
3708 summary_info += {'gdb': config_host['HAVE_GDB_BIN']}
3709 endif
3710 summary_info += {'iasl': iasl}
3711 summary_info += {'genisoimage': config_host['GENISOIMAGE']}
3712 if targetos == 'windows' and have_ga
3713 summary_info += {'wixl': wixl}
3714 endif
3715 if slirp_opt != 'disabled' and have_system
3716 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false}
3717 endif
3718 summary(summary_info, bool_yn: true, section: 'Host binaries')
3719
3720 # Configurable features
3721 summary_info = {}
3722 summary_info += {'Documentation': build_docs}
3723 summary_info += {'system-mode emulation': have_system}
3724 summary_info += {'user-mode emulation': have_user}
3725 summary_info += {'block layer': have_block}
3726 summary_info += {'Install blobs': get_option('install_blobs')}
3727 summary_info += {'module support': config_host.has_key('CONFIG_MODULES')}
3728 if config_host.has_key('CONFIG_MODULES')
3729 summary_info += {'alternative module path': get_option('module_upgrades')}
3730 endif
3731 summary_info += {'fuzzing support': get_option('fuzzing')}
3732 if have_system
3733 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)}
3734 endif
3735 summary_info += {'Trace backends': ','.join(get_option('trace_backends'))}
3736 if 'simple' in get_option('trace_backends')
3737 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'}
3738 endif
3739 summary_info += {'D-Bus display': dbus_display}
3740 summary_info += {'QOM debugging': get_option('qom_cast_debug')}
3741 summary_info += {'vhost-kernel support': have_vhost_kernel}
3742 summary_info += {'vhost-net support': have_vhost_net}
3743 summary_info += {'vhost-user support': have_vhost_user}
3744 summary_info += {'vhost-user-crypto support': have_vhost_user_crypto}
3745 summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server}
3746 summary_info += {'vhost-vdpa support': have_vhost_vdpa}
3747 summary_info += {'build guest agent': have_ga}
3748 summary(summary_info, bool_yn: true, section: 'Configurable features')
3749
3750 # Compilation information
3751 summary_info = {}
3752 summary_info += {'host CPU': cpu}
3753 summary_info += {'host endianness': build_machine.endian()}
3754 summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())}
3755 summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())}
3756 if link_language == 'cpp'
3757 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())}
3758 else
3759 summary_info += {'C++ compiler': false}
3760 endif
3761 if targetos == 'darwin'
3762 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())}
3763 endif
3764 summary_info += {'CFLAGS': ' '.join(get_option('c_args')
3765 + ['-O' + get_option('optimization')]
3766 + (get_option('debug') ? ['-g'] : []))}
3767 if link_language == 'cpp'
3768 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args')
3769 + ['-O' + get_option('optimization')]
3770 + (get_option('debug') ? ['-g'] : []))}
3771 endif
3772 if targetos == 'darwin'
3773 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args')
3774 + ['-O' + get_option('optimization')]
3775 + (get_option('debug') ? ['-g'] : []))}
3776 endif
3777 link_args = get_option(link_language + '_link_args')
3778 if link_args.length() > 0
3779 summary_info += {'LDFLAGS': ' '.join(link_args)}
3780 endif
3781 summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)}
3782 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)}
3783 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)}
3784 summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)}
3785 summary_info += {'profiler': get_option('profiler')}
3786 summary_info += {'link-time optimization (LTO)': get_option('b_lto')}
3787 summary_info += {'PIE': get_option('b_pie')}
3788 summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}
3789 summary_info += {'malloc trim support': has_malloc_trim}
3790 summary_info += {'membarrier': have_membarrier}
3791 summary_info += {'debug stack usage': get_option('debug_stack_usage')}
3792 summary_info += {'mutex debugging': get_option('debug_mutex')}
3793 summary_info += {'memory allocator': get_option('malloc')}
3794 summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')}
3795 summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')}
3796 summary_info += {'gprof enabled': get_option('gprof')}
3797 summary_info += {'gcov': get_option('b_coverage')}
3798 summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')}
3799 summary_info += {'CFI support': get_option('cfi')}
3800 if get_option('cfi')
3801 summary_info += {'CFI debug support': get_option('cfi_debug')}
3802 endif
3803 summary_info += {'strip binaries': get_option('strip')}
3804 summary_info += {'sparse': sparse}
3805 summary_info += {'mingw32 support': targetos == 'windows'}
3806 summary(summary_info, bool_yn: true, section: 'Compilation')
3807
3808 # snarf the cross-compilation information for tests
3809 summary_info = {}
3810 have_cross = false
3811 foreach target: target_dirs
3812 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak'
3813 if fs.exists(tcg_mak)
3814 config_cross_tcg = keyval.load(tcg_mak)
3815 if 'CC' in config_cross_tcg
3816 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']}
3817 have_cross = true
3818 endif
3819 endif
3820 endforeach
3821 if have_cross
3822 summary(summary_info, bool_yn: true, section: 'Cross compilers')
3823 endif
3824
3825 # Targets and accelerators
3826 summary_info = {}
3827 if have_system
3828 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')}
3829 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')}
3830 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')}
3831 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')}
3832 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')}
3833 summary_info += {'Xen support': xen.found()}
3834 if xen.found()
3835 summary_info += {'xen ctrl version': xen.version()}
3836 endif
3837 endif
3838 summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')}
3839 if config_all.has_key('CONFIG_TCG')
3840 if get_option('tcg_interpreter')
3841 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'}
3842 else
3843 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)}
3844 endif
3845 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')}
3846 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')}
3847 endif
3848 summary_info += {'target list': ' '.join(target_dirs)}
3849 if have_system
3850 summary_info += {'default devices': get_option('default_devices')}
3851 summary_info += {'out of process emulation': multiprocess_allowed}
3852 summary_info += {'vfio-user server': vfio_user_server_allowed}
3853 endif
3854 summary(summary_info, bool_yn: true, section: 'Targets and accelerators')
3855
3856 # Block layer
3857 summary_info = {}
3858 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
3859 summary_info += {'coroutine pool': have_coroutine_pool}
3860 if have_block
3861 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')}
3862 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')}
3863 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')}
3864 summary_info += {'VirtFS support': have_virtfs}
3865 summary_info += {'build virtiofs daemon': have_virtiofsd}
3866 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')}
3867 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')}
3868 summary_info += {'bochs support': get_option('bochs').allowed()}
3869 summary_info += {'cloop support': get_option('cloop').allowed()}
3870 summary_info += {'dmg support': get_option('dmg').allowed()}
3871 summary_info += {'qcow v1 support': get_option('qcow1').allowed()}
3872 summary_info += {'vdi support': get_option('vdi').allowed()}
3873 summary_info += {'vvfat support': get_option('vvfat').allowed()}
3874 summary_info += {'qed support': get_option('qed').allowed()}
3875 summary_info += {'parallels support': get_option('parallels').allowed()}
3876 summary_info += {'FUSE exports': fuse}
3877 summary_info += {'VDUSE block exports': have_vduse_blk_export}
3878 endif
3879 summary(summary_info, bool_yn: true, section: 'Block layer support')
3880
3881 # Crypto
3882 summary_info = {}
3883 summary_info += {'TLS priority': get_option('tls_priority')}
3884 summary_info += {'GNUTLS support': gnutls}
3885 if gnutls.found()
3886 summary_info += {' GNUTLS crypto': gnutls_crypto.found()}
3887 endif
3888 summary_info += {'libgcrypt': gcrypt}
3889 summary_info += {'nettle': nettle}
3890 if nettle.found()
3891 summary_info += {' XTS': xts != 'private'}
3892 endif
3893 summary_info += {'AF_ALG support': have_afalg}
3894 summary_info += {'rng-none': get_option('rng_none')}
3895 summary_info += {'Linux keyring': have_keyring}
3896 summary(summary_info, bool_yn: true, section: 'Crypto')
3897
3898 # Libraries
3899 summary_info = {}
3900 if targetos == 'darwin'
3901 summary_info += {'Cocoa support': cocoa}
3902 summary_info += {'vmnet.framework support': vmnet}
3903 endif
3904 summary_info += {'SDL support': sdl}
3905 summary_info += {'SDL image support': sdl_image}
3906 summary_info += {'GTK support': gtk}
3907 summary_info += {'pixman': pixman}
3908 summary_info += {'VTE support': vte}
3909 summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp}
3910 summary_info += {'libtasn1': tasn1}
3911 summary_info += {'PAM': pam}
3912 summary_info += {'iconv support': iconv}
3913 summary_info += {'curses support': curses}
3914 summary_info += {'virgl support': virgl}
3915 summary_info += {'curl support': curl}
3916 summary_info += {'Multipath support': mpathpersist}
3917 summary_info += {'PNG support': png}
3918 summary_info += {'VNC support': vnc}
3919 if vnc.found()
3920 summary_info += {'VNC SASL support': sasl}
3921 summary_info += {'VNC JPEG support': jpeg}
3922 endif
3923 if targetos not in ['darwin', 'haiku', 'windows']
3924 summary_info += {'OSS support': oss}
3925 elif targetos == 'darwin'
3926 summary_info += {'CoreAudio support': coreaudio}
3927 elif targetos == 'windows'
3928 summary_info += {'DirectSound support': dsound}
3929 endif
3930 if targetos == 'linux'
3931 summary_info += {'ALSA support': alsa}
3932 summary_info += {'PulseAudio support': pulse}
3933 endif
3934 summary_info += {'JACK support': jack}
3935 summary_info += {'brlapi support': brlapi}
3936 summary_info += {'vde support': vde}
3937 summary_info += {'netmap support': have_netmap}
3938 summary_info += {'l2tpv3 support': have_l2tpv3}
3939 summary_info += {'Linux AIO support': libaio}
3940 summary_info += {'Linux io_uring support': linux_io_uring}
3941 summary_info += {'ATTR/XATTR support': libattr}
3942 summary_info += {'RDMA support': rdma}
3943 summary_info += {'PVRDMA support': have_pvrdma}
3944 summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt}
3945 summary_info += {'libcap-ng support': libcap_ng}
3946 summary_info += {'bpf support': libbpf}
3947 summary_info += {'spice protocol support': spice_protocol}
3948 if spice_protocol.found()
3949 summary_info += {' spice server support': spice}
3950 endif
3951 summary_info += {'rbd support': rbd}
3952 summary_info += {'smartcard support': cacard}
3953 summary_info += {'U2F support': u2f}
3954 summary_info += {'libusb': libusb}
3955 summary_info += {'usb net redir': usbredir}
3956 summary_info += {'OpenGL support (epoxy)': opengl}
3957 summary_info += {'GBM': gbm}
3958 summary_info += {'libiscsi support': libiscsi}
3959 summary_info += {'libnfs support': libnfs}
3960 if targetos == 'windows'
3961 if have_ga
3962 summary_info += {'QGA VSS support': have_qga_vss}
3963 endif
3964 endif
3965 summary_info += {'seccomp support': seccomp}
3966 summary_info += {'GlusterFS support': glusterfs}
3967 summary_info += {'TPM support': have_tpm}
3968 summary_info += {'libssh support': libssh}
3969 summary_info += {'lzo support': lzo}
3970 summary_info += {'snappy support': snappy}
3971 summary_info += {'bzip2 support': libbzip2}
3972 summary_info += {'lzfse support': liblzfse}
3973 summary_info += {'zstd support': zstd}
3974 summary_info += {'NUMA host support': numa}
3975 summary_info += {'capstone': capstone}
3976 summary_info += {'libpmem support': libpmem}
3977 summary_info += {'libdaxctl support': libdaxctl}
3978 summary_info += {'libudev': libudev}
3979 # Dummy dependency, keep .found()
3980 summary_info += {'FUSE lseek': fuse_lseek.found()}
3981 summary_info += {'selinux': selinux}
3982 summary(summary_info, bool_yn: true, section: 'Dependencies')
3983
3984 if not supported_cpus.contains(cpu)
3985 message()
3986 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!')
3987 message()
3988 message('CPU host architecture ' + cpu + ' support is not currently maintained.')
3989 message('The QEMU project intends to remove support for this host CPU in')
3990 message('a future release if nobody volunteers to maintain it and to')
3991 message('provide a build host for our continuous integration setup.')
3992 message('configure has succeeded and you can continue to build, but')
3993 message('if you care about QEMU on this platform you should contact')
3994 message('us upstream at qemu-devel@nongnu.org.')
3995 endif
3996
3997 if not supported_oses.contains(targetos)
3998 message()
3999 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!')
4000 message()
4001 message('Host OS ' + targetos + 'support is not currently maintained.')
4002 message('The QEMU project intends to remove support for this host OS in')
4003 message('a future release if nobody volunteers to maintain it and to')
4004 message('provide a build host for our continuous integration setup.')
4005 message('configure has succeeded and you can continue to build, but')
4006 message('if you care about QEMU on this platform you should contact')
4007 message('us upstream at qemu-devel@nongnu.org.')
4008 endif