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