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