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