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