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