1project('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 6add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true) 7add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow']) 8add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough']) 9 10meson.add_postconf_script(find_program('scripts/symlink-install-tree.py')) 11 12#################### 13# Global variables # 14#################### 15 16not_found = dependency('', required: false) 17keyval = import('keyval') 18ss = import('sourceset') 19fs = import('fs') 20 21host_os = host_machine.system() 22config_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.) 29tmpdir = meson.current_build_dir() / 'meson-private/temp' 30 31if get_option('qemu_suffix').startswith('/') 32 error('qemu_suffix cannot start with a /') 33endif 34 35qemu_confdir = get_option('sysconfdir') / get_option('qemu_suffix') 36qemu_datadir = get_option('datadir') / get_option('qemu_suffix') 37qemu_docdir = get_option('docdir') / get_option('qemu_suffix') 38qemu_moddir = get_option('libdir') / get_option('qemu_suffix') 39 40qemu_desktopdir = get_option('datadir') / 'applications' 41qemu_icondir = get_option('datadir') / 'icons' 42 43genh = [] 44qapi_trace_events = [] 45 46bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin'] 47supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] 48supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64', 49 'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64'] 50 51cpu = host_machine.cpu_family() 52 53target_dirs = config_host['TARGET_DIRS'].split() 54 55############ 56# Programs # 57############ 58 59sh = find_program('sh') 60python = import('python').find_installation() 61 62cc = meson.get_compiler('c') 63all_languages = ['c'] 64if host_os == 'windows' and add_languages('cpp', required: false, native: false) 65 all_languages += ['cpp'] 66 cxx = meson.get_compiler('cpp') 67endif 68if host_os == 'darwin' and \ 69 add_languages('objc', required: true, native: false) 70 all_languages += ['objc'] 71 objc = meson.get_compiler('objc') 72endif 73 74dtrace = not_found 75stap = not_found 76if '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 88endif 89 90if get_option('iasl') == '' 91 iasl = find_program('iasl', required: false) 92else 93 iasl = find_program(get_option('iasl'), required: true) 94endif 95 96edk2_targets = [ 'arm-softmmu', 'aarch64-softmmu', 'i386-softmmu', 'x86_64-softmmu' ] 97unpack_edk2_blobs = false 98foreach 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 104endforeach 105 106##################### 107# Option validation # 108##################### 109 110# Fuzzing 111if 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') 120endif 121 122# Tracing backends 123if 'ftrace' in get_option('trace_backends') and host_os != 'linux' 124 error('ftrace is supported only on Linux') 125endif 126if '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') 134endif 135 136# Miscellaneous Linux-only features 137get_option('mpath') \ 138 .require(host_os == 'linux', error_message: 'Multipath is supported only on Linux') 139 140multiprocess_allowed = get_option('multiprocess') \ 141 .require(host_os == 'linux', error_message: 'Multiprocess QEMU is supported only on Linux') \ 142 .allowed() 143 144vfio_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 148have_tpm = get_option('tpm') \ 149 .require(host_os != 'windows', error_message: 'TPM emulation only available on POSIX systems') \ 150 .allowed() 151 152# vhost 153have_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() 157have_vhost_vdpa = get_option('vhost_vdpa') \ 158 .require(host_os == 'linux', 159 error_message: 'vhost-vdpa is only available on Linux').allowed() 160have_vhost_kernel = get_option('vhost_kernel') \ 161 .require(host_os == 'linux', 162 error_message: 'vhost-kernel is only available on Linux').allowed() 163have_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 167have_vhost = have_vhost_user or have_vhost_vdpa or have_vhost_kernel 168 169have_vhost_net_user = have_vhost_user and get_option('vhost_net').allowed() 170have_vhost_net_vdpa = have_vhost_vdpa and get_option('vhost_net').allowed() 171have_vhost_net_kernel = have_vhost_kernel and get_option('vhost_net').allowed() 172have_vhost_net = have_vhost_net_kernel or have_vhost_net_user or have_vhost_net_vdpa 173 174# type of binaries to build 175have_linux_user = false 176have_bsd_user = false 177have_system = false 178foreach 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') 182endforeach 183have_user = have_linux_user or have_bsd_user 184 185have_tools = get_option('tools') \ 186 .disable_auto_if(not have_system) \ 187 .allowed() 188have_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() 193have_block = have_system or have_tools 194 195enable_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 206if cpu not in supported_cpus 207 host_arch = 'unknown' 208elif cpu == 'x86' 209 host_arch = 'i386' 210elif cpu == 'mips64' 211 host_arch = 'mips' 212elif cpu in ['riscv32', 'riscv64'] 213 host_arch = 'riscv' 214else 215 host_arch = cpu 216endif 217 218if cpu in ['x86', 'x86_64'] 219 kvm_targets = ['i386-softmmu', 'x86_64-softmmu'] 220elif cpu == 'aarch64' 221 kvm_targets = ['aarch64-softmmu'] 222elif cpu == 's390x' 223 kvm_targets = ['s390x-softmmu'] 224elif cpu in ['ppc', 'ppc64'] 225 kvm_targets = ['ppc-softmmu', 'ppc64-softmmu'] 226elif cpu in ['mips', 'mips64'] 227 kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu'] 228elif cpu in ['riscv32'] 229 kvm_targets = ['riscv32-softmmu'] 230elif cpu in ['riscv64'] 231 kvm_targets = ['riscv64-softmmu'] 232elif cpu in ['loongarch64'] 233 kvm_targets = ['loongarch64-softmmu'] 234else 235 kvm_targets = [] 236endif 237accelerator_targets = { 'CONFIG_KVM': kvm_targets } 238 239if cpu in ['x86', 'x86_64'] 240 xen_targets = ['i386-softmmu', 'x86_64-softmmu'] 241elif cpu in ['arm', 'aarch64'] 242 # i386 emulator provides xenpv machine type for multiple architectures 243 xen_targets = ['i386-softmmu', 'x86_64-softmmu', 'aarch64-softmmu'] 244else 245 xen_targets = [] 246endif 247accelerator_targets += { 'CONFIG_XEN': xen_targets } 248 249if cpu in ['aarch64'] 250 accelerator_targets += { 251 'CONFIG_HVF': ['aarch64-softmmu'] 252 } 253endif 254 255if 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 } 261endif 262 263modular_tcg = [] 264# Darwin does not support references to thread-local variables in modules 265if host_os != 'darwin' 266 modular_tcg = ['i386-softmmu', 'x86_64-softmmu'] 267endif 268 269################## 270# Compiler flags # 271################## 272 273foreach 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 291endforeach 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 299qemu_common_flags = [ 300 '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE', 301 '-fno-strict-aliasing', '-fno-common', '-fwrapv' ] 302qemu_cflags = [] 303qemu_ldflags = [] 304 305if 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 311elif 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__' 316elif host_os == 'haiku' 317 qemu_common_flags += ['-DB_USE_POSITIVE_POSIX_ERRORS', '-D_BSD_SOURCE', '-fPIC'] 318endif 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 323if 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 337endif 338 339if get_option('prefer_static') 340 qemu_ldflags += get_option('b_pie') ? '-static-pie' : '-static' 341endif 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. :( 358if not get_option('b_pie') 359 qemu_common_flags += cc.get_supported_arguments('-fno-pie', '-no-pie') 360endif 361 362if 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') 386endif 387 388coroutine_backend = get_option('coroutine_backend') 389ucontext_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. 399supported_backends = [] 400if host_os == 'windows' 401 supported_backends += ['windows'] 402else 403 if host_os != 'darwin' and cc.links(ucontext_probe) 404 supported_backends += ['ucontext'] 405 endif 406 supported_backends += ['sigaltstack'] 407endif 408 409if coroutine_backend == 'auto' 410 coroutine_backend = supported_backends[0] 411elif coroutine_backend not in supported_backends 412 error('"@0@" backend requested but not available. Available backends: @1@' \ 413 .format(coroutine_backend, ', '.join(supported_backends))) 414endif 415 416# Compiles if SafeStack *not* enabled 417safe_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 }''' 427if 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 436endif 437if get_option('safe_stack') and coroutine_backend != 'ucontext' 438 error('SafeStack is only supported with the ucontext coroutine backend') 439endif 440 441if 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 453endif 454 455# Thread sanitizer is, for now, much noisier than the other sanitizers; 456# keep it separate until that is not the case. 457if 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 468endif 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. 472qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now') 473 474if 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') 477endif 478 479if 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 508endif 509 510if 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) 548endif 549 550# Check further flags that make QEMU more robust against malicious parties 551 552hardening_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 568if 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' 573endif 574 575qemu_common_flags += cc.get_supported_arguments(hardening_flags) 576 577add_global_arguments(qemu_common_flags, native: false, language: all_languages) 578add_global_link_arguments(qemu_ldflags, native: false, language: all_languages) 579 580# Collect warning flags we want to set, sorted alphabetically 581warn_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 615if host_os != 'darwin' 616 warn_flags += ['-Wthread-safety'] 617endif 618 619# Set up C++ compiler flags 620qemu_cxxflags = [] 621if 'cpp' in all_languages 622 qemu_cxxflags = ['-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS', '-D__STDC_FORMAT_MACROS'] + qemu_cflags 623endif 624 625add_project_arguments(qemu_cflags, native: false, language: 'c') 626add_project_arguments(cc.get_supported_arguments(warn_flags), native: false, language: 'c') 627if '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') 630endif 631if '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') 634endif 635if host_os == 'linux' 636 add_project_arguments('-isystem', meson.current_source_dir() / 'linux-headers', 637 '-isystem', 'linux-headers', 638 language: all_languages) 639endif 640 641add_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... 647host_include = meson.current_source_dir() / 'host/include/' 648if fs.is_dir(host_include / host_arch) 649 add_project_arguments('-iquote', host_include / host_arch, 650 language: all_languages) 651endif 652# ... followed by the generic fallback. 653add_project_arguments('-iquote', host_include / 'generic', 654 language: all_languages) 655 656sparse = find_program('cgcc', required: get_option('sparse')) 657if 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']) 663endif 664 665##################################### 666# Host-specific libraries and flags # 667##################################### 668 669libm = cc.find_library('m', required: false) 670threads = dependency('threads') 671util = cc.find_library('util', required: false) 672winmm = [] 673socket = [] 674version_res = [] 675coref = [] 676iokit = [] 677emulator_link_args = [] 678midl = not_found 679widl = not_found 680pathcch = not_found 681host_dsosuf = '.so' 682if 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' 694elif host_os == 'darwin' 695 coref = dependency('appleframeworks', modules: 'CoreFoundation') 696 iokit = dependency('appleframeworks', modules: 'IOKit', required: false) 697 host_dsosuf = '.dylib' 698elif host_os == 'sunos' 699 socket = [cc.find_library('socket'), 700 cc.find_library('nsl'), 701 cc.find_library('resolv')] 702elif host_os == 'haiku' 703 socket = [cc.find_library('posix_error_mapper'), 704 cc.find_library('network'), 705 cc.find_library('bsd')] 706elif 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 711endif 712 713############################################### 714# Host-specific configuration of accelerators # 715############################################### 716 717accelerators = [] 718if get_option('kvm').allowed() and host_os == 'linux' 719 accelerators += 'CONFIG_KVM' 720endif 721if 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 728endif 729 730hvf = not_found 731if 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 737endif 738 739nvmm = not_found 740if host_os == 'netbsd' 741 nvmm = cc.find_library('nvmm', required: get_option('nvmm')) 742 if nvmm.found() 743 accelerators += 'CONFIG_NVMM' 744 endif 745endif 746 747tcg_arch = host_arch 748if 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' 772endif 773 774if 'CONFIG_KVM' not in accelerators and get_option('kvm').enabled() 775 error('KVM not available on this platform') 776endif 777if 'CONFIG_HVF' not in accelerators and get_option('hvf').enabled() 778 error('HVF not available on this platform') 779endif 780if 'CONFIG_NVMM' not in accelerators and get_option('nvmm').enabled() 781 error('NVMM not available on this platform') 782endif 783if 'CONFIG_WHPX' not in accelerators and get_option('whpx').enabled() 784 error('WHPX not available on this platform') 785endif 786 787xen = not_found 788if 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 856endif 857have_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 872glib_req_ver = '>=2.66.0' 873glib_pc = dependency('glib-2.0', version: glib_req_ver, required: true, 874 method: 'pkg-config') 875glib_cflags = [] 876if enable_modules 877 gmodule = dependency('gmodule-export-2.0', version: glib_req_ver, required: true, 878 method: 'pkg-config') 879elif get_option('plugins') 880 gmodule = dependency('gmodule-no-export-2.0', version: glib_req_ver, required: true, 881 method: 'pkg-config') 882else 883 gmodule = not_found 884endif 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 888if host_os == 'windows' and get_option('prefer_static') 889 glib_cflags += ['-DGLIB_STATIC_COMPILATION'] 890endif 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 897if 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.''') 911endif 912 913glib = 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 920glib_has_gslice = glib.version().version_compare('<2.75.3') 921 922# override glib dep to include the above refinements 923meson.override_dependency('glib-2.0', glib) 924 925# The path to glib.h is added to all compilation commands. 926add_project_dependencies(glib.partial_dependency(compile_args: true, includes: true), 927 native: false, language: all_languages) 928 929gio = not_found 930gdbus_codegen = not_found 931gdbus_codegen_error = '@0@ requires gdbus-codegen, please install libgio' 932if 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 955endif 956if 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' 959endif 960 961xml_pp = find_program('scripts/xml-preprocess.py') 962 963lttng = not_found 964if 'ust' in get_option('trace_backends') 965 lttng = dependency('lttng-ust', required: true, version: '>= 2.1', 966 method: 'pkg-config') 967endif 968pixman = not_found 969if 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') 972endif 973 974zlib = dependency('zlib', required: true) 975 976libaio = not_found 977if 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')) 980endif 981 982linux_io_uring_test = ''' 983 #include <liburing.h> 984 #include <linux/errqueue.h> 985 986 int main(void) { return 0; }''' 987 988linux_io_uring = not_found 989if 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 996endif 997 998libnfs = not_found 999if 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') 1003endif 1004 1005libattr_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 1015libattr = not_found 1016have_old_libattr = false 1017if 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 1035endif 1036 1037cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'], 1038 required: get_option('cocoa')) 1039 1040vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet')) 1041if 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 1050endif 1051 1052seccomp = not_found 1053seccomp_has_sysrawrc = false 1054if 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 1063endif 1064 1065libcap_ng = not_found 1066if 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')) 1069endif 1070if 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 1083endif 1084 1085if get_option('xkbcommon').auto() and not have_system and not have_tools 1086 xkbcommon = not_found 1087else 1088 xkbcommon = dependency('xkbcommon', required: get_option('xkbcommon'), 1089 method: 'pkg-config') 1090endif 1091 1092slirp = not_found 1093if 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 1110endif 1111 1112vde = not_found 1113if 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')) 1116endif 1117if 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 1132endif 1133 1134pulse = not_found 1135if not get_option('pa').auto() or (host_os == 'linux' and have_system) 1136 pulse = dependency('libpulse', required: get_option('pa'), 1137 method: 'pkg-config') 1138endif 1139alsa = not_found 1140if not get_option('alsa').auto() or (host_os == 'linux' and have_system) 1141 alsa = dependency('alsa', required: get_option('alsa'), 1142 method: 'pkg-config') 1143endif 1144jack = not_found 1145if not get_option('jack').auto() or have_system 1146 jack = dependency('jack', required: get_option('jack'), 1147 method: 'pkg-config') 1148endif 1149pipewire = not_found 1150if 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') 1154endif 1155sndio = not_found 1156if not get_option('sndio').auto() or have_system 1157 sndio = dependency('sndio', required: get_option('sndio'), 1158 method: 'pkg-config') 1159endif 1160 1161spice_protocol = not_found 1162if 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') 1166endif 1167spice = not_found 1168if 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') 1176endif 1177spice_headers = spice.partial_dependency(compile_args: true, includes: true) 1178 1179rt = cc.find_library('rt', required: false) 1180 1181libiscsi = not_found 1182if 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') 1186endif 1187zstd = not_found 1188if 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') 1192endif 1193virgl = not_found 1194 1195have_vhost_user_gpu = have_tools and host_os == 'linux' and pixman.found() 1196if 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')) 1200endif 1201rutabaga = not_found 1202if 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')) 1206endif 1207blkio = not_found 1208if not get_option('blkio').auto() or have_block 1209 blkio = dependency('blkio', 1210 method: 'pkg-config', 1211 required: get_option('blkio')) 1212endif 1213curl = not_found 1214if 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')) 1218endif 1219libudev = not_found 1220if host_os == 'linux' and (have_system or have_tools) 1221 libudev = dependency('libudev', 1222 method: 'pkg-config', 1223 required: get_option('libudev')) 1224endif 1225 1226mpathlibs = [libudev] 1227mpathpersist = not_found 1228if 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 1277endif 1278 1279iconv = not_found 1280curses = not_found 1281if 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 1370endif 1371 1372brlapi = not_found 1373if 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 1387endif 1388 1389sdl = not_found 1390if not get_option('sdl').auto() or have_system 1391 sdl = dependency('sdl2', required: get_option('sdl')) 1392 sdl_image = not_found 1393endif 1394if 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') 1407else 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 1413endif 1414 1415rbd = not_found 1416if 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 1439endif 1440 1441glusterfs = not_found 1442glusterfs_ftruncate_has_stat = false 1443glusterfs_iocb_has_stat = false 1444if 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 1476endif 1477 1478hv_balloon = false 1479if 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 1500endif 1501 1502libssh = not_found 1503if 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')) 1507endif 1508 1509libbzip2 = not_found 1510if 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 1523endif 1524 1525liblzfse = not_found 1526if not get_option('lzfse').auto() or have_block 1527 liblzfse = cc.find_library('lzfse', has_headers: ['lzfse.h'], 1528 required: get_option('lzfse')) 1529endif 1530if 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 1539endif 1540 1541oss = not_found 1542if 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 1556endif 1557dsound = not_found 1558if 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 1568endif 1569 1570coreaudio = not_found 1571if not get_option('coreaudio').auto() or (host_os == 'darwin' and have_system) 1572 coreaudio = dependency('appleframeworks', modules: 'CoreAudio', 1573 required: get_option('coreaudio')) 1574endif 1575 1576opengl = not_found 1577if 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 1585endif 1586gbm = not_found 1587if (have_system or have_tools) and (virgl.found() or opengl.found()) 1588 gbm = dependency('gbm', method: 'pkg-config', required: false) 1589endif 1590have_vhost_user_gpu = have_vhost_user_gpu and virgl.found() and opengl.found() and gbm.found() 1591 1592gnutls = not_found 1593gnutls_crypto = not_found 1594if 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 1619endif 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. 1626gcrypt = not_found 1627nettle = not_found 1628hogweed = not_found 1629crypto_sm4 = not_found 1630xts = 'none' 1631 1632if get_option('nettle').enabled() and get_option('gcrypt').enabled() 1633 error('Only one of gcrypt & nettle can be enabled') 1634endif 1635 1636# Explicit nettle/gcrypt request, so ignore gnutls for crypto 1637if get_option('nettle').enabled() or get_option('gcrypt').enabled() 1638 gnutls_crypto = not_found 1639endif 1640 1641if 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 1687endif 1688 1689capstone = not_found 1690if 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 1706endif 1707 1708gmp = dependency('gmp', required: false, method: 'pkg-config') 1709if nettle.found() and gmp.found() 1710 hogweed = dependency('hogweed', version: '>=3.4', 1711 method: 'pkg-config', 1712 required: get_option('nettle')) 1713endif 1714 1715 1716gtk = not_found 1717gtkx11 = not_found 1718vte = not_found 1719have_gtk_clipboard = get_option('gtk_clipboard').enabled() 1720 1721if 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 1744endif 1745 1746x11 = not_found 1747if gtkx11.found() 1748 x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found()) 1749endif 1750png = not_found 1751if get_option('png').allowed() and have_system 1752 png = dependency('libpng', version: '>=1.6.34', required: get_option('png'), 1753 method: 'pkg-config') 1754endif 1755vnc = not_found 1756jpeg = not_found 1757sasl = not_found 1758if 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 1772endif 1773 1774pam = not_found 1775if 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')) 1778endif 1779if 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 1796endif 1797 1798snappy = not_found 1799if not get_option('snappy').auto() or have_system 1800 snappy = cc.find_library('snappy', has_headers: ['snappy-c.h'], 1801 required: get_option('snappy')) 1802endif 1803if 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 1812endif 1813 1814lzo = not_found 1815if not get_option('lzo').auto() or have_system 1816 lzo = cc.find_library('lzo2', has_headers: ['lzo/lzo1x.h'], 1817 required: get_option('lzo')) 1818endif 1819if 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 1828endif 1829 1830numa = not_found 1831if 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')) 1834endif 1835if 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 1845endif 1846 1847fdt = not_found 1848fdt_opt = get_option('fdt') 1849if fdt_opt == 'enabled' and get_option('wrap_mode') == 'nodownload' 1850 fdt_opt = 'system' 1851endif 1852if 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 1866endif 1867if 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') 1873endif 1874 1875rdma = not_found 1876if 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 1888endif 1889 1890cacard = not_found 1891if not get_option('smartcard').auto() or have_system 1892 cacard = dependency('libcacard', required: get_option('smartcard'), 1893 version: '>=2.5.1', method: 'pkg-config') 1894endif 1895u2f = not_found 1896if not get_option('u2f').auto() or have_system 1897 u2f = dependency('u2f-emu', required: get_option('u2f'), 1898 method: 'pkg-config') 1899endif 1900canokey = not_found 1901if not get_option('canokey').auto() or have_system 1902 canokey = dependency('canokey-qemu', required: get_option('canokey'), 1903 method: 'pkg-config') 1904endif 1905usbredir = not_found 1906if 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') 1909endif 1910libusb = not_found 1911if 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') 1914endif 1915 1916libpmem = not_found 1917if not get_option('libpmem').auto() or have_system 1918 libpmem = dependency('libpmem', required: get_option('libpmem'), 1919 method: 'pkg-config') 1920endif 1921libdaxctl = not_found 1922if not get_option('libdaxctl').auto() or have_system 1923 libdaxctl = dependency('libdaxctl', required: get_option('libdaxctl'), 1924 version: '>=57', method: 'pkg-config') 1925endif 1926tasn1 = not_found 1927if gnutls.found() 1928 tasn1 = dependency('libtasn1', 1929 method: 'pkg-config') 1930endif 1931keyutils = not_found 1932if not get_option('libkeyutils').auto() or have_block 1933 keyutils = dependency('libkeyutils', required: get_option('libkeyutils'), 1934 method: 'pkg-config') 1935endif 1936 1937has_gettid = cc.has_function('gettid') 1938 1939# libselinux 1940selinux = dependency('libselinux', 1941 required: get_option('selinux'), 1942 method: 'pkg-config') 1943 1944# Malloc tests 1945 1946malloc = [] 1947if 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>') 1951else 1952 has_malloc_trim = false 1953 malloc = cc.find_library(get_option('malloc'), required: true) 1954endif 1955if 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 1961endif 1962 1963gnu_source_prefix = ''' 1964 #ifndef _GNU_SOURCE 1965 #define _GNU_SOURCE 1966 #endif 1967''' 1968 1969# Check whether the glibc provides STATX_BASIC_STATS 1970 1971has_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 1975has_statx_mnt_id = cc.has_header_symbol('sys/stat.h', 'STATX_MNT_ID', prefix: gnu_source_prefix) 1976 1977have_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 1985if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() 1986 error('Cannot enable fuse-lseek while fuse is disabled') 1987endif 1988 1989fuse = dependency('fuse3', required: get_option('fuse'), 1990 version: '>=3.1', method: 'pkg-config') 1991 1992fuse_lseek = not_found 1993if 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 2004endif 2005 2006have_libvduse = (host_os == 'linux') 2007if get_option('libvduse').enabled() 2008 if host_os != 'linux' 2009 error('libvduse requires linux') 2010 endif 2011elif get_option('libvduse').disabled() 2012 have_libvduse = false 2013endif 2014 2015have_vduse_blk_export = (have_libvduse and host_os == 'linux') 2016if 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 2022elif get_option('vduse_blk_export').disabled() 2023 have_vduse_blk_export = false 2024endif 2025 2026# libbpf 2027bpf_version = '1.1.0' 2028libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config') 2029if 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 2045endif 2046 2047# libxdp 2048libxdp = not_found 2049if 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') 2052endif 2053 2054# libdw 2055libdw = not_found 2056if 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')) 2061endif 2062 2063################# 2064# config-host.h # 2065################# 2066 2067config_host_data = configuration_data() 2068 2069audio_drivers_selected = [] 2070if 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 2106endif 2107config_host_data.set('CONFIG_AUDIO_DRIVERS', 2108 '"' + '", "'.join(audio_drivers_selected) + '", ') 2109 2110have_host_block_device = (host_os != 'darwin' or 2111 cc.has_header('IOKit/storage/IOMedia.h')) 2112 2113dbus_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 2120have_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 2130have_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 2137if get_option('block_drv_ro_whitelist') == '' 2138 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '') 2139else 2140 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', 2141 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ') 2142endif 2143if get_option('block_drv_rw_whitelist') == '' 2144 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '') 2145else 2146 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', 2147 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ') 2148endif 2149 2150foreach k : get_option('trace_backends') 2151 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true) 2152endforeach 2153config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file')) 2154config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority')) 2155if iasl.found() 2156 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path()) 2157endif 2158config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) 2159config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) 2160config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) 2161config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir) 2162config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir) 2163 2164qemu_firmwarepath = '' 2165foreach k : get_option('qemu_firmwarepath') 2166 qemu_firmwarepath += '"' + get_option('prefix') / k + '", ' 2167endforeach 2168config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath) 2169 2170config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir')) 2171config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir) 2172config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir')) 2173config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir')) 2174config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) 2175config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) 2176 2177if 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()) 2183endif 2184 2185have_slirp_smbd = get_option('slirp_smbd') \ 2186 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \ 2187 .allowed() 2188if 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) 2194endif 2195 2196config_host_data.set('HOST_' + host_arch.to_upper(), 1) 2197 2198kvm_targets_c = '""' 2199if get_option('kvm').allowed() and host_os == 'linux' 2200 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"' 2201endif 2202config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c) 2203 2204if get_option('module_upgrades') and not enable_modules 2205 error('Cannot enable module-upgrades as modules are not enabled') 2206endif 2207config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades')) 2208 2209config_host_data.set('CONFIG_ATTR', libattr.found()) 2210config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools')) 2211config_host_data.set('CONFIG_BRLAPI', brlapi.found()) 2212config_host_data.set('CONFIG_BSD', host_os in bsd_oses) 2213config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2214config_host_data.set('CONFIG_COCOA', cocoa.found()) 2215config_host_data.set('CONFIG_DARWIN', host_os == 'darwin') 2216config_host_data.set('CONFIG_FDT', fdt.found()) 2217config_host_data.set('CONFIG_FUZZ', get_option('fuzzing')) 2218config_host_data.set('CONFIG_GCOV', get_option('b_coverage')) 2219config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 2220config_host_data.set('CONFIG_LINUX', host_os == 'linux') 2221config_host_data.set('CONFIG_POSIX', host_os != 'windows') 2222config_host_data.set('CONFIG_WIN32', host_os == 'windows') 2223config_host_data.set('CONFIG_LZO', lzo.found()) 2224config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 2225config_host_data.set('CONFIG_BLKIO', blkio.found()) 2226if blkio.found() 2227 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD', 2228 blkio.version().version_compare('>=1.3.0')) 2229endif 2230config_host_data.set('CONFIG_CURL', curl.found()) 2231config_host_data.set('CONFIG_CURSES', curses.found()) 2232config_host_data.set('CONFIG_GBM', gbm.found()) 2233config_host_data.set('CONFIG_GIO', gio.found()) 2234config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 2235if 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) 2242endif 2243config_host_data.set('CONFIG_GTK', gtk.found()) 2244config_host_data.set('CONFIG_VTE', vte.found()) 2245config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard) 2246config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser')) 2247config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 2248config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 2249config_host_data.set('CONFIG_EBPF', libbpf.found()) 2250config_host_data.set('CONFIG_AF_XDP', libxdp.found()) 2251config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 2252config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 2253config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 2254config_host_data.set('CONFIG_LIBSSH', libssh.found()) 2255config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 2256config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 2257config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 2258config_host_data.set('CONFIG_MODULES', enable_modules) 2259config_host_data.set('CONFIG_NUMA', numa.found()) 2260if numa.found() 2261 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY', 2262 cc.has_function('numa_has_preferred_many', 2263 dependencies: numa)) 2264endif 2265config_host_data.set('CONFIG_OPENGL', opengl.found()) 2266config_host_data.set('CONFIG_PLUGIN', get_option('plugins')) 2267config_host_data.set('CONFIG_RBD', rbd.found()) 2268config_host_data.set('CONFIG_RDMA', rdma.found()) 2269config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable')) 2270config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack')) 2271config_host_data.set('CONFIG_SDL', sdl.found()) 2272config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 2273config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 2274if seccomp.found() 2275 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) 2276endif 2277config_host_data.set('CONFIG_PIXMAN', pixman.found()) 2278config_host_data.set('CONFIG_SLIRP', slirp.found()) 2279config_host_data.set('CONFIG_SNAPPY', snappy.found()) 2280config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos') 2281if get_option('tcg').allowed() 2282 config_host_data.set('CONFIG_TCG', 1) 2283 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci') 2284endif 2285config_host_data.set('CONFIG_TPM', have_tpm) 2286config_host_data.set('CONFIG_TSAN', get_option('tsan')) 2287config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 2288config_host_data.set('CONFIG_VDE', vde.found()) 2289config_host_data.set('CONFIG_VHOST', have_vhost) 2290config_host_data.set('CONFIG_VHOST_NET', have_vhost_net) 2291config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user) 2292config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa) 2293config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel) 2294config_host_data.set('CONFIG_VHOST_USER', have_vhost_user) 2295config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto) 2296config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa) 2297config_host_data.set('CONFIG_VMNET', vmnet.found()) 2298config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 2299config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export) 2300config_host_data.set('CONFIG_PNG', png.found()) 2301config_host_data.set('CONFIG_VNC', vnc.found()) 2302config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 2303config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 2304if 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)) 2309endif 2310config_host_data.set('CONFIG_VIRTFS', have_virtfs) 2311config_host_data.set('CONFIG_VTE', vte.found()) 2312config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 2313config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 2314config_host_data.set('CONFIG_GETTID', has_gettid) 2315config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 2316config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 2317config_host_data.set('CONFIG_TASN1', tasn1.found()) 2318config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 2319config_host_data.set('CONFIG_NETTLE', nettle.found()) 2320config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found()) 2321config_host_data.set('CONFIG_HOGWEED', hogweed.found()) 2322config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 2323config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 2324config_host_data.set('CONFIG_STATX', has_statx) 2325config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 2326config_host_data.set('CONFIG_ZSTD', zstd.found()) 2327config_host_data.set('CONFIG_FUSE', fuse.found()) 2328config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 2329config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 2330if spice_protocol.found() 2331config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 2332config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 2333config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 2334endif 2335config_host_data.set('CONFIG_SPICE', spice.found()) 2336config_host_data.set('CONFIG_X11', x11.found()) 2337config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 2338config_host_data.set('CONFIG_CFI', get_option('cfi')) 2339config_host_data.set('CONFIG_SELINUX', selinux.found()) 2340config_host_data.set('CONFIG_XEN_BACKEND', xen.found()) 2341config_host_data.set('CONFIG_LIBDW', libdw.found()) 2342if 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) 2349endif 2350config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 2351config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 2352config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 2353config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 2354 2355config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 2356config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 2357 2358have_coroutine_pool = get_option('coroutine_pool') 2359if get_option('debug_stack_usage') and have_coroutine_pool 2360 message('Disabling coroutine pool to measure stack usage') 2361 have_coroutine_pool = false 2362endif 2363config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool) 2364config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock')) 2365config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 2366config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 2367config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg')) 2368config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap')) 2369config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 2370config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) 2371 2372# has_header 2373config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 2374config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 2375config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 2376config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 2377config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 2378config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 2379config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 2380config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 2381config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 2382if host_os == 'windows' 2383 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h')) 2384endif 2385 2386# has_function 2387config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range')) 2388config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 2389config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 2390config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 2391config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 2392config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 2393config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix)) 2394config_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() 2397config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 2398config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 2399config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 2400config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 2401config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 2402config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 2403config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 2404config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 2405config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 2406config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 2407config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 2408config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 2409config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 2410config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) 2411config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice) 2412config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 2413config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 2414config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 2415if 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>')) 2420endif 2421if 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>')) 2426endif 2427 2428have_asan_fiber = false 2429if 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.') 2435else 2436 have_asan_fiber = true 2437endif 2438config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber) 2439 2440have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init') 2441have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1') 2442inotify = not_found 2443if (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 2452endif 2453config_host_data.set('CONFIG_INOTIFY', have_inotify_init) 2454config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1) 2455 2456# has_header_symbol 2457config_host_data.set('CONFIG_BLKZONED', 2458 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE')) 2459config_host_data.set('CONFIG_EPOLL_CREATE1', 2460 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 2461config_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')) 2464config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 2465 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 2466config_host_data.set('CONFIG_FIEMAP', 2467 cc.has_header('linux/fiemap.h') and 2468 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 2469config_host_data.set('CONFIG_GETRANDOM', 2470 cc.has_function('getrandom') and 2471 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 2472config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 2473 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 2474config_host_data.set('CONFIG_RTNETLINK', 2475 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 2476config_host_data.set('CONFIG_SYSMACROS', 2477 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 2478config_host_data.set('HAVE_OPTRESET', 2479 cc.has_header_symbol('getopt.h', 'optreset')) 2480config_host_data.set('HAVE_IPPROTO_MPTCP', 2481 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 2482 2483# has_member 2484config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 2485 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 2486 prefix: '#include <signal.h>')) 2487config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 2488 cc.has_member('struct stat', 'st_atim', 2489 prefix: '#include <sys/stat.h>')) 2490config_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 2495config_host_data.set('CONFIG_IOVEC', 2496 cc.has_type('struct iovec', 2497 prefix: '#include <sys/uio.h>')) 2498config_host_data.set('HAVE_UTMPX', 2499 cc.has_type('struct utmpx', 2500 prefix: '#include <utmpx.h>')) 2501 2502config_host_data.set('CONFIG_EVENTFD', cc.links(''' 2503 #include <sys/eventfd.h> 2504 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 2505config_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 2515has_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); }''') 2520missing_madvise_proto = false 2521if 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); }''') 2534endif 2535config_host_data.set('CONFIG_MADVISE', has_madvise) 2536config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 2537 2538config_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); }''')) 2541config_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''')) 2548config_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 2553config_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)) 2564config_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)) 2574config_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)) 2586config_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)) 2597config_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)) 2614config_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); }''')) 2618config_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 2631config_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 2637have_l2tpv3 = false 2638if 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>''') 2643endif 2644config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2645 2646have_netmap = false 2647if 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 2660endif 2661config_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. 2667config_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 2675config_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. 2685config_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 2698has_int128_type = cc.compiles(''' 2699 __int128_t a; 2700 __uint128_t b; 2701 int main(void) { b = a; }''') 2702config_host_data.set('CONFIG_INT128_TYPE', has_int128_type) 2703 2704has_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 }''') 2713config_host_data.set('CONFIG_INT128', has_int128) 2714 2715if 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 2753endif 2754 2755config_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 2761config_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 2774have_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() 2785config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 2786 2787have_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 }''') 2803config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 2804 2805config_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 2817config_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 2829config_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. 2843config_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 2851if get_option('membarrier').disabled() 2852 have_membarrier = false 2853elif host_os == 'windows' 2854 have_membarrier = true 2855elif 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 }''') 2866endif 2867config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 2868 .require(have_membarrier, error_message: 'membarrier system call not available') \ 2869 .allowed()) 2870 2871have_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() 2883config_host_data.set('CONFIG_AF_ALG', have_afalg) 2884 2885config_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 2890have_vss = false 2891have_vss_sdk = false # old xp/2003 SDK 2892if 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') 2898endif 2899config_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. 2903if 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')) 2911endif 2912 2913if 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 2932endif 2933 2934######################## 2935# Target configuration # 2936######################## 2937 2938minikconf = find_program('scripts/minikconf.py') 2939 2940config_all_accel = {} 2941config_all_devices = {} 2942config_devices_mak_list = [] 2943config_devices_h = {} 2944config_target_h = {} 2945config_target_mak = {} 2946 2947disassemblers = { 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 2969have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 2970host_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 2988ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 2989 2990default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 2991actual_target_dirs = [] 2992fdt_required = [] 2993foreach 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} 3129endforeach 3130target_dirs = actual_target_dirs 3131 3132target_configs_h = [] 3133foreach target: target_dirs 3134 target_configs_h += config_target_h[target] 3135 target_configs_h += config_devices_h.get(target, []) 3136endforeach 3137genh += 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 3144if fdt_required.length() > 0 3145 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3146endif 3147 3148############### 3149# Subprojects # 3150############### 3151 3152libvfio_user_dep = not_found 3153if 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') 3156endif 3157 3158vhost_user = not_found 3159if host_os == 'linux' and have_vhost_user 3160 libvhost_user = subproject('libvhost-user') 3161 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3162endif 3163 3164libvduse = not_found 3165if have_libvduse 3166 libvduse_proj = subproject('libvduse') 3167 libvduse = libvduse_proj.get_variable('libvduse_dep') 3168endif 3169 3170##################### 3171# Generated sources # 3172##################### 3173 3174genh += configure_file(output: 'config-host.h', configuration: config_host_data) 3175 3176hxtool = find_program('scripts/hxtool') 3177shaderinclude = find_program('scripts/shaderinclude.py') 3178qapi_gen = find_program('scripts/qapi-gen.py') 3179qapi_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 3196tracetool = [ 3197 python, files('scripts/tracetool.py'), 3198 '--backend=' + ','.join(get_option('trace_backends')) 3199] 3200tracetool_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 3221qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3222 meson.current_source_dir(), 3223 get_option('pkgversion'), meson.project_version()] 3224qemu_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) 3230genh += qemu_version 3231 3232hxdep = [] 3233hx_headers = [ 3234 ['qemu-options.hx', 'qemu-options.def'], 3235 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3236] 3237if have_system 3238 hx_headers += [ 3239 ['hmp-commands.hx', 'hmp-commands.h'], 3240 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3241 ] 3242endif 3243foreach 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@']) 3249endforeach 3250genh += 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 3258trace_events_subdirs = [ 3259 'crypto', 3260 'qapi', 3261 'qom', 3262 'monitor', 3263 'util', 3264 'gdbstub', 3265] 3266if have_linux_user 3267 trace_events_subdirs += [ 'linux-user' ] 3268endif 3269if have_bsd_user 3270 trace_events_subdirs += [ 'bsd-user' ] 3271endif 3272if have_block 3273 trace_events_subdirs += [ 3274 'authz', 3275 'block', 3276 'io', 3277 'nbd', 3278 'scsi', 3279 ] 3280endif 3281if 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 ] 3344endif 3345if 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 ] 3362endif 3363 3364################### 3365# Collect sources # 3366################### 3367 3368authz_ss = ss.source_set() 3369blockdev_ss = ss.source_set() 3370block_ss = ss.source_set() 3371chardev_ss = ss.source_set() 3372common_ss = ss.source_set() 3373crypto_ss = ss.source_set() 3374hwcore_ss = ss.source_set() 3375io_ss = ss.source_set() 3376qmp_ss = ss.source_set() 3377qom_ss = ss.source_set() 3378system_ss = ss.source_set() 3379specific_fuzz_ss = ss.source_set() 3380specific_ss = ss.source_set() 3381stub_ss = ss.source_set() 3382trace_ss = ss.source_set() 3383user_ss = ss.source_set() 3384util_ss = ss.source_set() 3385 3386# accel modules 3387qtest_module_ss = ss.source_set() 3388tcg_module_ss = ss.source_set() 3389 3390modules = {} 3391target_modules = {} 3392hw_arch = {} 3393target_arch = {} 3394target_system_arch = {} 3395target_user_arch = {} 3396 3397# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3398# that is filled in by qapi/. 3399subdir('qapi') 3400subdir('qobject') 3401subdir('stubs') 3402subdir('trace') 3403subdir('util') 3404subdir('qom') 3405subdir('authz') 3406subdir('crypto') 3407subdir('ui') 3408subdir('gdbstub') 3409if have_system 3410 subdir('hw') 3411else 3412 subdir('hw/core') 3413endif 3414 3415if 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') 3418endif 3419 3420qom_ss = qom_ss.apply({}) 3421libqom = static_library('qom', qom_ss.sources() + genh, 3422 dependencies: [qom_ss.dependencies()], 3423 name_suffix: 'fa', 3424 build_by_default: false) 3425qom = declare_dependency(link_whole: libqom) 3426 3427event_loop_base = files('event-loop-base.c') 3428event_loop_base = static_library('event-loop-base', 3429 sources: event_loop_base + genh, 3430 name_suffix: 'fa', 3431 build_by_default: false) 3432event_loop_base = declare_dependency(link_whole: event_loop_base, 3433 dependencies: [qom]) 3434 3435stub_ss = stub_ss.apply({}) 3436 3437util_ss.add_all(trace_ss) 3438util_ss = util_ss.apply({}) 3439libqemuutil = 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]) 3443qemuutil = declare_dependency(link_with: libqemuutil, 3444 sources: genh + version_res, 3445 dependencies: [event_loop_base]) 3446 3447if 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') 3453endif 3454 3455subdir('audio') 3456subdir('io') 3457subdir('chardev') 3458subdir('fsdev') 3459subdir('dump') 3460 3461if 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 3490endif 3491 3492common_ss.add(files('cpu-common.c')) 3493specific_ss.add(files('cpu-target.c')) 3494 3495subdir('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. 3504pagevary = files('page-vary-common.c') 3505if 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) 3513endif 3514common_ss.add(pagevary) 3515specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3516 3517subdir('backends') 3518subdir('disas') 3519subdir('migration') 3520subdir('monitor') 3521subdir('net') 3522subdir('replay') 3523subdir('semihosting') 3524subdir('stats') 3525subdir('tcg') 3526subdir('fpu') 3527subdir('accel') 3528subdir('plugins') 3529subdir('ebpf') 3530 3531common_user_inc = [] 3532 3533subdir('common-user') 3534subdir('bsd-user') 3535subdir('linux-user') 3536 3537# needed for fuzzing binaries 3538subdir('tests/qtest/libqos') 3539subdir('tests/qtest/fuzz') 3540 3541# accel modules 3542tcg_real_module_ss = ss.source_set() 3543tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3544specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3545target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3546 'tcg': tcg_real_module_ss }} 3547 3548############################################## 3549# Internal static_libraries and dependencies # 3550############################################## 3551 3552modinfo_collect = find_program('scripts/modinfo-collect.py') 3553modinfo_generate = find_program('scripts/modinfo-generate.py') 3554modinfo_files = [] 3555 3556block_mods = [] 3557system_mods = [] 3558foreach 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 3593endforeach 3594 3595foreach 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 3628endforeach 3629 3630if 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 3648endif 3649 3650nm = find_program('nm') 3651undefsym = find_program('scripts/undefsym.py') 3652block_syms = custom_target('block.syms', output: 'block.syms', 3653 input: [libqemuutil, block_mods], 3654 capture: true, 3655 command: [undefsym, nm, '@INPUT@']) 3656qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3657 input: [libqemuutil, system_mods], 3658 capture: true, 3659 command: [undefsym, nm, '@INPUT@']) 3660 3661authz_ss = authz_ss.apply({}) 3662libauthz = static_library('authz', authz_ss.sources() + genh, 3663 dependencies: [authz_ss.dependencies()], 3664 name_suffix: 'fa', 3665 build_by_default: false) 3666 3667authz = declare_dependency(link_whole: libauthz, 3668 dependencies: qom) 3669 3670crypto_ss = crypto_ss.apply({}) 3671libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3672 dependencies: [crypto_ss.dependencies()], 3673 name_suffix: 'fa', 3674 build_by_default: false) 3675 3676crypto = declare_dependency(link_whole: libcrypto, 3677 dependencies: [authz, qom]) 3678 3679io_ss = io_ss.apply({}) 3680libio = 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 3686io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 3687 3688libmigration = static_library('migration', sources: migration_files + genh, 3689 name_suffix: 'fa', 3690 build_by_default: false) 3691migration = declare_dependency(link_with: libmigration, 3692 dependencies: [zlib, qom, io]) 3693system_ss.add(migration) 3694 3695block_ss = block_ss.apply({}) 3696libblock = 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 3702block = declare_dependency(link_whole: [libblock], 3703 link_args: '@block.syms', 3704 dependencies: [crypto, io]) 3705 3706blockdev_ss = blockdev_ss.apply({}) 3707libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3708 dependencies: blockdev_ss.dependencies(), 3709 name_suffix: 'fa', 3710 build_by_default: false) 3711 3712blockdev = declare_dependency(link_whole: [libblockdev], 3713 dependencies: [block, event_loop_base]) 3714 3715qmp_ss = qmp_ss.apply({}) 3716libqmp = static_library('qmp', qmp_ss.sources() + genh, 3717 dependencies: qmp_ss.dependencies(), 3718 name_suffix: 'fa', 3719 build_by_default: false) 3720 3721qmp = declare_dependency(link_whole: [libqmp]) 3722 3723libchardev = static_library('chardev', chardev_ss.sources() + genh, 3724 name_suffix: 'fa', 3725 dependencies: chardev_ss.dependencies(), 3726 build_by_default: false) 3727 3728chardev = declare_dependency(link_whole: libchardev) 3729 3730hwcore_ss = hwcore_ss.apply({}) 3731libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3732 name_suffix: 'fa', 3733 build_by_default: false) 3734hwcore = declare_dependency(link_whole: libhwcore) 3735common_ss.add(hwcore) 3736 3737########### 3738# Targets # 3739########### 3740 3741emulator_modules = [] 3742foreach 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) 3749endforeach 3750if emulator_modules.length() > 0 3751 alias_target('modules', emulator_modules) 3752endif 3753 3754system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3755common_ss.add(qom, qemuutil) 3756 3757common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 3758common_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. 3763common_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 3771feature_to_c = find_program('scripts/feature_to_c.py') 3772 3773if host_os == 'darwin' 3774 entitlement = find_program('scripts/entitlement.sh') 3775endif 3776 3777traceable = [] 3778emulators = {} 3779foreach 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 3960endforeach 3961 3962# Other build targets 3963 3964if 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 3971endif 3972 3973subdir('qga') 3974 3975# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3976# when we don't build tools or system 3977if 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) 3981endif 3982 3983if 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 4030endif 4031 4032if 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 4056endif 4057 4058subdir('scripts') 4059subdir('tools') 4060subdir('pc-bios') 4061subdir('docs') 4062subdir('tests') 4063if gtk.found() 4064 subdir('po') 4065endif 4066 4067if 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) 4091endif 4092 4093######################### 4094# Configuration summary # 4095######################### 4096 4097# Build environment 4098summary_info = {} 4099summary_info += {'Build directory': meson.current_build_dir()} 4100summary_info += {'Source path': meson.current_source_dir()} 4101summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4102summary(summary_info, bool_yn: true, section: 'Build environment') 4103 4104# Directories 4105summary_info += {'Install prefix': get_option('prefix')} 4106summary_info += {'BIOS directory': qemu_datadir} 4107pathsep = host_os == 'windows' ? ';' : ':' 4108summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4109summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4110summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4111summary_info += {'module directory': qemu_moddir} 4112summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4113summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4114summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4115if 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')} 4118else 4119 summary_info += {'local state directory': 'queried at runtime'} 4120endif 4121summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4122summary(summary_info, bool_yn: true, section: 'Directories') 4123 4124# Host binaries 4125summary_info = {} 4126summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4127summary_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). 4133if config_host.has_key('GDB') 4134 summary_info += {'gdb': config_host['GDB']} 4135endif 4136summary_info += {'iasl': iasl} 4137summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4138if host_os == 'windows' and have_ga 4139 summary_info += {'wixl': wixl} 4140endif 4141if slirp.found() and have_system 4142 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4143endif 4144summary(summary_info, bool_yn: true, section: 'Host binaries') 4145 4146# Configurable features 4147summary_info = {} 4148summary_info += {'Documentation': build_docs} 4149summary_info += {'system-mode emulation': have_system} 4150summary_info += {'user-mode emulation': have_user} 4151summary_info += {'block layer': have_block} 4152summary_info += {'Install blobs': get_option('install_blobs')} 4153summary_info += {'module support': enable_modules} 4154if enable_modules 4155 summary_info += {'alternative module path': get_option('module_upgrades')} 4156endif 4157summary_info += {'fuzzing support': get_option('fuzzing')} 4158if have_system 4159 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4160endif 4161summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4162if 'simple' in get_option('trace_backends') 4163 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4164endif 4165summary_info += {'D-Bus display': dbus_display} 4166summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4167summary_info += {'Relocatable install': get_option('relocatable')} 4168summary_info += {'vhost-kernel support': have_vhost_kernel} 4169summary_info += {'vhost-net support': have_vhost_net} 4170summary_info += {'vhost-user support': have_vhost_user} 4171summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4172summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4173summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4174summary_info += {'build guest agent': have_ga} 4175summary(summary_info, bool_yn: true, section: 'Configurable features') 4176 4177# Compilation information 4178summary_info = {} 4179summary_info += {'host CPU': cpu} 4180summary_info += {'host endianness': build_machine.endian()} 4181summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4182summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4183if 'cpp' in all_languages 4184 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4185else 4186 summary_info += {'C++ compiler': false} 4187endif 4188if 'objc' in all_languages 4189 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4190else 4191 summary_info += {'Objective-C compiler': false} 4192endif 4193option_cflags = (get_option('debug') ? ['-g'] : []) 4194if get_option('optimization') != 'plain' 4195 option_cflags += ['-O' + get_option('optimization')] 4196endif 4197summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4198if 'cpp' in all_languages 4199 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4200endif 4201if 'objc' in all_languages 4202 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4203endif 4204link_args = get_option('c_link_args') 4205if link_args.length() > 0 4206 summary_info += {'LDFLAGS': ' '.join(link_args)} 4207endif 4208summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4209if 'cpp' in all_languages 4210 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4211endif 4212if 'objc' in all_languages 4213 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4214endif 4215summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4216summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4217summary_info += {'PIE': get_option('b_pie')} 4218summary_info += {'static build': get_option('prefer_static')} 4219summary_info += {'malloc trim support': has_malloc_trim} 4220summary_info += {'membarrier': have_membarrier} 4221summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4222summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4223summary_info += {'mutex debugging': get_option('debug_mutex')} 4224summary_info += {'memory allocator': get_option('malloc')} 4225summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4226summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4227summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 4228summary_info += {'gcov': get_option('b_coverage')} 4229summary_info += {'thread sanitizer': get_option('tsan')} 4230summary_info += {'CFI support': get_option('cfi')} 4231if get_option('cfi') 4232 summary_info += {'CFI debug support': get_option('cfi_debug')} 4233endif 4234summary_info += {'strip binaries': get_option('strip')} 4235summary_info += {'sparse': sparse} 4236summary_info += {'mingw32 support': host_os == 'windows'} 4237summary(summary_info, bool_yn: true, section: 'Compilation') 4238 4239# snarf the cross-compilation information for tests 4240summary_info = {} 4241have_cross = false 4242foreach 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 4251endforeach 4252if have_cross 4253 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4254endif 4255 4256# Targets and accelerators 4257summary_info = {} 4258if 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')} 4268endif 4269summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4270if 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 4281endif 4282summary_info += {'target list': ' '.join(target_dirs)} 4283if 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} 4287endif 4288summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4289 4290# Block layer 4291summary_info = {} 4292summary_info += {'coroutine backend': coroutine_backend} 4293summary_info += {'coroutine pool': have_coroutine_pool} 4294if 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} 4314endif 4315summary(summary_info, bool_yn: true, section: 'Block layer support') 4316 4317# Crypto 4318summary_info = {} 4319summary_info += {'TLS priority': get_option('tls_priority')} 4320summary_info += {'GNUTLS support': gnutls} 4321if gnutls.found() 4322 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4323endif 4324summary_info += {'libgcrypt': gcrypt} 4325summary_info += {'nettle': nettle} 4326if nettle.found() 4327 summary_info += {' XTS': xts != 'private'} 4328endif 4329summary_info += {'SM4 ALG support': crypto_sm4} 4330summary_info += {'AF_ALG support': have_afalg} 4331summary_info += {'rng-none': get_option('rng_none')} 4332summary_info += {'Linux keyring': have_keyring} 4333summary_info += {'Linux keyutils': keyutils} 4334summary(summary_info, bool_yn: true, section: 'Crypto') 4335 4336# UI 4337summary_info = {} 4338if host_os == 'darwin' 4339 summary_info += {'Cocoa support': cocoa} 4340endif 4341summary_info += {'SDL support': sdl} 4342summary_info += {'SDL image support': sdl_image} 4343summary_info += {'GTK support': gtk} 4344summary_info += {'pixman': pixman} 4345summary_info += {'VTE support': vte} 4346summary_info += {'PNG support': png} 4347summary_info += {'VNC support': vnc} 4348if vnc.found() 4349 summary_info += {'VNC SASL support': sasl} 4350 summary_info += {'VNC JPEG support': jpeg} 4351endif 4352summary_info += {'spice protocol support': spice_protocol} 4353if spice_protocol.found() 4354 summary_info += {' spice server support': spice} 4355endif 4356summary_info += {'curses support': curses} 4357summary_info += {'brlapi support': brlapi} 4358summary(summary_info, bool_yn: true, section: 'User interface') 4359 4360# Graphics backends 4361summary_info = {} 4362summary_info += {'VirGL support': virgl} 4363summary_info += {'Rutabaga support': rutabaga} 4364summary(summary_info, bool_yn: true, section: 'Graphics backends') 4365 4366# Audio backends 4367summary_info = {} 4368if host_os not in ['darwin', 'haiku', 'windows'] 4369 summary_info += {'OSS support': oss} 4370 summary_info += {'sndio support': sndio} 4371elif host_os == 'darwin' 4372 summary_info += {'CoreAudio support': coreaudio} 4373elif host_os == 'windows' 4374 summary_info += {'DirectSound support': dsound} 4375endif 4376if host_os == 'linux' 4377 summary_info += {'ALSA support': alsa} 4378 summary_info += {'PulseAudio support': pulse} 4379endif 4380summary_info += {'PipeWire support': pipewire} 4381summary_info += {'JACK support': jack} 4382summary(summary_info, bool_yn: true, section: 'Audio backends') 4383 4384# Network backends 4385summary_info = {} 4386if host_os == 'darwin' 4387 summary_info += {'vmnet.framework support': vmnet} 4388endif 4389summary_info += {'AF_XDP support': libxdp} 4390summary_info += {'slirp support': slirp} 4391summary_info += {'vde support': vde} 4392summary_info += {'netmap support': have_netmap} 4393summary_info += {'l2tpv3 support': have_l2tpv3} 4394summary(summary_info, bool_yn: true, section: 'Network backends') 4395 4396# Libraries 4397summary_info = {} 4398summary_info += {'libtasn1': tasn1} 4399summary_info += {'PAM': pam} 4400summary_info += {'iconv support': iconv} 4401summary_info += {'blkio support': blkio} 4402summary_info += {'curl support': curl} 4403summary_info += {'Multipath support': mpathpersist} 4404summary_info += {'Linux AIO support': libaio} 4405summary_info += {'Linux io_uring support': linux_io_uring} 4406summary_info += {'ATTR/XATTR support': libattr} 4407summary_info += {'RDMA support': rdma} 4408summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4409summary_info += {'libcap-ng support': libcap_ng} 4410summary_info += {'bpf support': libbpf} 4411summary_info += {'rbd support': rbd} 4412summary_info += {'smartcard support': cacard} 4413summary_info += {'U2F support': u2f} 4414summary_info += {'libusb': libusb} 4415summary_info += {'usb net redir': usbredir} 4416summary_info += {'OpenGL support (epoxy)': opengl} 4417summary_info += {'GBM': gbm} 4418summary_info += {'libiscsi support': libiscsi} 4419summary_info += {'libnfs support': libnfs} 4420if host_os == 'windows' 4421 if have_ga 4422 summary_info += {'QGA VSS support': have_qga_vss} 4423 endif 4424endif 4425summary_info += {'seccomp support': seccomp} 4426summary_info += {'GlusterFS support': glusterfs} 4427summary_info += {'hv-balloon support': hv_balloon} 4428summary_info += {'TPM support': have_tpm} 4429summary_info += {'libssh support': libssh} 4430summary_info += {'lzo support': lzo} 4431summary_info += {'snappy support': snappy} 4432summary_info += {'bzip2 support': libbzip2} 4433summary_info += {'lzfse support': liblzfse} 4434summary_info += {'zstd support': zstd} 4435summary_info += {'NUMA host support': numa} 4436summary_info += {'capstone': capstone} 4437summary_info += {'libpmem support': libpmem} 4438summary_info += {'libdaxctl support': libdaxctl} 4439summary_info += {'libudev': libudev} 4440# Dummy dependency, keep .found() 4441summary_info += {'FUSE lseek': fuse_lseek.found()} 4442summary_info += {'selinux': selinux} 4443summary_info += {'libdw': libdw} 4444if host_os == 'freebsd' 4445 summary_info += {'libinotify-kqueue': inotify} 4446endif 4447summary(summary_info, bool_yn: true, section: 'Dependencies') 4448 4449if 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 4463endif 4464 4465if 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 + '.') 4476endif 4477 4478if 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.') 4482endif 4483 4484actually_reloc = get_option('relocatable') 4485# check if get_relocated_path() is actually able to relocate paths 4486if 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 4491endif 4492if 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.') 4500endif 4501