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