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