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() 3515stub_ss = ss.source_set() 3516trace_ss = ss.source_set() 3517user_ss = ss.source_set() 3518util_ss = ss.source_set() 3519 3520# accel modules 3521qtest_module_ss = ss.source_set() 3522tcg_module_ss = ss.source_set() 3523 3524modules = {} 3525target_modules = {} 3526hw_arch = {} 3527target_arch = {} 3528target_system_arch = {} 3529target_user_arch = {} 3530 3531# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3532# that is filled in by qapi/. 3533subdir('qapi') 3534subdir('qobject') 3535subdir('stubs') 3536subdir('trace') 3537subdir('util') 3538subdir('qom') 3539subdir('authz') 3540subdir('crypto') 3541subdir('ui') 3542subdir('gdbstub') 3543if have_system 3544 subdir('hw') 3545else 3546 subdir('hw/core') 3547endif 3548 3549if enable_modules 3550 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3551 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3552endif 3553 3554qom_ss = qom_ss.apply({}) 3555libqom = static_library('qom', qom_ss.sources() + genh, 3556 dependencies: [qom_ss.dependencies()], 3557 build_by_default: false) 3558qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3559 dependencies: qom_ss.dependencies()) 3560 3561event_loop_base = files('event-loop-base.c') 3562event_loop_base = static_library('event-loop-base', 3563 sources: event_loop_base + genh, 3564 build_by_default: false) 3565event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3566 dependencies: [qom]) 3567 3568stub_ss = stub_ss.apply({}) 3569 3570util_ss.add_all(trace_ss) 3571util_ss = util_ss.apply({}) 3572libqemuutil = static_library('qemuutil', 3573 build_by_default: false, 3574 sources: util_ss.sources() + stub_ss.sources() + genh, 3575 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3576qemuutil = declare_dependency(link_with: libqemuutil, 3577 sources: genh + version_res, 3578 dependencies: [event_loop_base]) 3579 3580if have_system or have_user 3581 decodetree = generator(find_program('scripts/decodetree.py'), 3582 output: 'decode-@BASENAME@.c.inc', 3583 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3584 subdir('libdecnumber') 3585 subdir('target') 3586endif 3587 3588subdir('audio') 3589subdir('io') 3590subdir('chardev') 3591subdir('fsdev') 3592subdir('dump') 3593 3594if have_block 3595 block_ss.add(files( 3596 'block.c', 3597 'blockjob.c', 3598 'job.c', 3599 'qemu-io-cmds.c', 3600 )) 3601 if config_host_data.get('CONFIG_REPLICATION') 3602 block_ss.add(files('replication.c')) 3603 endif 3604 3605 subdir('nbd') 3606 subdir('scsi') 3607 subdir('block') 3608 3609 blockdev_ss.add(files( 3610 'blockdev.c', 3611 'blockdev-nbd.c', 3612 'iothread.c', 3613 'job-qmp.c', 3614 )) 3615 3616 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3617 # os-win32.c does not 3618 if host_os == 'windows' 3619 system_ss.add(files('os-win32.c')) 3620 else 3621 blockdev_ss.add(files('os-posix.c')) 3622 endif 3623endif 3624 3625common_ss.add(files('cpu-common.c')) 3626specific_ss.add(files('cpu-target.c')) 3627 3628subdir('system') 3629 3630# Work around a gcc bug/misfeature wherein constant propagation looks 3631# through an alias: 3632# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3633# to guess that a const variable is always zero. Without lto, this is 3634# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3635# without lto, not even the alias is required -- we simply use different 3636# declarations in different compilation units. 3637pagevary = files('page-vary-common.c') 3638if get_option('b_lto') 3639 pagevary_flags = ['-fno-lto'] 3640 if get_option('cfi') 3641 pagevary_flags += '-fno-sanitize=cfi-icall' 3642 endif 3643 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3644 c_args: pagevary_flags) 3645 pagevary = declare_dependency(link_with: pagevary) 3646endif 3647common_ss.add(pagevary) 3648specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3649 3650subdir('backends') 3651subdir('disas') 3652subdir('migration') 3653subdir('monitor') 3654subdir('net') 3655subdir('replay') 3656subdir('semihosting') 3657subdir('stats') 3658subdir('tcg') 3659subdir('fpu') 3660subdir('accel') 3661subdir('plugins') 3662subdir('ebpf') 3663 3664common_user_inc = [] 3665 3666subdir('common-user') 3667subdir('bsd-user') 3668subdir('linux-user') 3669 3670# needed for fuzzing binaries 3671subdir('tests/qtest/libqos') 3672subdir('tests/qtest/fuzz') 3673 3674# accel modules 3675tcg_real_module_ss = ss.source_set() 3676tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3677specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3678target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3679 'tcg': tcg_real_module_ss }} 3680 3681############################################## 3682# Internal static_libraries and dependencies # 3683############################################## 3684 3685modinfo_collect = find_program('scripts/modinfo-collect.py') 3686modinfo_generate = find_program('scripts/modinfo-generate.py') 3687modinfo_files = [] 3688 3689block_mods = [] 3690system_mods = [] 3691emulator_modules = [] 3692foreach d, list : modules 3693 if not (d == 'block' ? have_block : have_system) 3694 continue 3695 endif 3696 3697 foreach m, module_ss : list 3698 if enable_modules 3699 module_ss.add(modulecommon) 3700 module_ss = module_ss.apply(config_all_devices, strict: false) 3701 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3702 dependencies: module_ss.dependencies(), pic: true) 3703 if d == 'block' 3704 block_mods += sl 3705 else 3706 system_mods += sl 3707 endif 3708 emulator_modules += shared_module(sl.name(), 3709 name_prefix: '', 3710 objects: sl.extract_all_objects(recursive: false), 3711 dependencies: module_ss.dependencies(), 3712 install: true, 3713 install_dir: qemu_moddir) 3714 if module_ss.sources() != [] 3715 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3716 # input. Sources can be used multiple times but objects are 3717 # unique when it comes to lookup in compile_commands.json. 3718 # Depnds on a mesion version with 3719 # https://github.com/mesonbuild/meson/pull/8900 3720 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3721 output: d + '-' + m + '.modinfo', 3722 input: module_ss.sources() + genh, 3723 capture: true, 3724 command: [modinfo_collect, module_ss.sources()]) 3725 endif 3726 else 3727 if d == 'block' 3728 block_ss.add_all(module_ss) 3729 else 3730 system_ss.add_all(module_ss) 3731 endif 3732 endif 3733 endforeach 3734endforeach 3735 3736foreach d, list : target_modules 3737 foreach m, module_ss : list 3738 if enable_modules 3739 module_ss.add(modulecommon) 3740 foreach target : target_dirs 3741 if target.endswith('-softmmu') 3742 config_target = config_target_mak[target] 3743 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3744 c_args = ['-DCOMPILING_PER_TARGET', 3745 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3746 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3747 target_module_ss = module_ss.apply(config_target, strict: false) 3748 if target_module_ss.sources() != [] 3749 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3750 sl = static_library(module_name, 3751 [genh, target_module_ss.sources()], 3752 dependencies: target_module_ss.dependencies(), 3753 include_directories: target_inc, 3754 c_args: c_args, 3755 pic: true) 3756 system_mods += sl 3757 emulator_modules += shared_module(sl.name(), 3758 name_prefix: '', 3759 objects: sl.extract_all_objects(recursive: false), 3760 dependencies: target_module_ss.dependencies(), 3761 install: true, 3762 install_dir: qemu_moddir) 3763 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3764 modinfo_files += custom_target(module_name + '.modinfo', 3765 output: module_name + '.modinfo', 3766 input: target_module_ss.sources() + genh, 3767 capture: true, 3768 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3769 endif 3770 endif 3771 endforeach 3772 else 3773 specific_ss.add_all(module_ss) 3774 endif 3775 endforeach 3776endforeach 3777 3778if enable_modules 3779 foreach target : target_dirs 3780 if target.endswith('-softmmu') 3781 config_target = config_target_mak[target] 3782 config_devices_mak = target + '-config-devices.mak' 3783 modinfo_src = custom_target('modinfo-' + target + '.c', 3784 output: 'modinfo-' + target + '.c', 3785 input: modinfo_files, 3786 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3787 capture: true) 3788 3789 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3790 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3791 3792 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3793 hw_arch[arch].add(modinfo_dep) 3794 endif 3795 endforeach 3796 3797 if emulator_modules.length() > 0 3798 alias_target('modules', emulator_modules) 3799 endif 3800endif 3801 3802nm = find_program('nm') 3803undefsym = find_program('scripts/undefsym.py') 3804block_syms = custom_target('block.syms', output: 'block.syms', 3805 input: [libqemuutil, block_mods], 3806 capture: true, 3807 command: [undefsym, nm, '@INPUT@']) 3808qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3809 input: [libqemuutil, system_mods], 3810 capture: true, 3811 command: [undefsym, nm, '@INPUT@']) 3812 3813authz_ss = authz_ss.apply({}) 3814libauthz = static_library('authz', authz_ss.sources() + genh, 3815 dependencies: [authz_ss.dependencies()], 3816 build_by_default: false) 3817 3818authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3819 dependencies: [authz_ss.dependencies(), qom]) 3820 3821crypto_ss = crypto_ss.apply({}) 3822libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3823 dependencies: [crypto_ss.dependencies()], 3824 build_by_default: false) 3825 3826crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3827 dependencies: [crypto_ss.dependencies(), authz, qom]) 3828 3829io_ss = io_ss.apply({}) 3830libio = static_library('io', io_ss.sources() + genh, 3831 dependencies: [io_ss.dependencies()], 3832 link_with: libqemuutil, 3833 build_by_default: false) 3834 3835io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3836 dependencies: [io_ss.dependencies(), crypto, qom]) 3837 3838libmigration = static_library('migration', sources: migration_files + genh, 3839 build_by_default: false) 3840migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3841 dependencies: [qom, io]) 3842system_ss.add(migration) 3843 3844block_ss = block_ss.apply({}) 3845libblock = static_library('block', block_ss.sources() + genh, 3846 dependencies: block_ss.dependencies(), 3847 build_by_default: false) 3848 3849block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3850 dependencies: [block_ss.dependencies(), crypto, io]) 3851 3852blockdev_ss = blockdev_ss.apply({}) 3853libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3854 dependencies: blockdev_ss.dependencies(), 3855 build_by_default: false) 3856 3857blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3858 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3859 3860qmp_ss = qmp_ss.apply({}) 3861libqmp = static_library('qmp', qmp_ss.sources() + genh, 3862 dependencies: qmp_ss.dependencies(), 3863 build_by_default: false) 3864 3865qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3866 dependencies: qmp_ss.dependencies()) 3867 3868libchardev = static_library('chardev', chardev_ss.sources() + genh, 3869 dependencies: chardev_ss.dependencies(), 3870 build_by_default: false) 3871 3872chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 3873 dependencies: chardev_ss.dependencies()) 3874 3875hwcore_ss = hwcore_ss.apply({}) 3876libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3877 build_by_default: false) 3878hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 3879common_ss.add(hwcore) 3880 3881########### 3882# Targets # 3883########### 3884 3885system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3886common_ss.add(qom, qemuutil) 3887 3888common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 3889common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3890 3891# Note that this library is never used directly (only through extract_objects) 3892# and is not built by default; therefore, source files not used by the build 3893# configuration will be in build.ninja, but are never built by default. 3894common_all = static_library('common', 3895 build_by_default: false, 3896 sources: common_ss.all_sources() + genh, 3897 include_directories: common_user_inc, 3898 implicit_include_directories: false, 3899 dependencies: common_ss.all_dependencies()) 3900 3901if have_rust and have_system 3902 rustc_args = run_command( 3903 find_program('scripts/rust/rustc_args.py'), 3904 '--config-headers', meson.project_build_root() / 'config-host.h', 3905 capture : true, 3906 check: true).stdout().strip().split() 3907 rustc_args += ['-D', 'unsafe_op_in_unsafe_fn'] 3908 bindgen_args = [ 3909 '--disable-header-comment', 3910 '--raw-line', '// @generated', 3911 '--ctypes-prefix', 'core::ffi', 3912 '--formatter', 'rustfmt', 3913 '--generate-block', 3914 '--generate-cstr', 3915 '--impl-debug', 3916 '--merge-extern-blocks', 3917 '--no-doc-comments', 3918 '--use-core', 3919 '--with-derive-default', 3920 '--no-size_t-is-usize', 3921 '--no-layout-tests', 3922 '--no-prepend-enum-name', 3923 '--allowlist-file', meson.project_source_root() + '/include/.*', 3924 '--allowlist-file', meson.project_source_root() + '/.*', 3925 '--allowlist-file', meson.project_build_root() + '/.*' 3926 ] 3927 c_enums = [ 3928 'DeviceCategory', 3929 'GpioPolarity', 3930 'MachineInitPhase', 3931 'MemoryDeviceInfoKind', 3932 'MigrationPolicy', 3933 'MigrationPriority', 3934 'QEMUChrEvent', 3935 'QEMUClockType', 3936 'device_endian', 3937 'module_init_type', 3938 ] 3939 foreach enum : c_enums 3940 bindgen_args += ['--rustified-enum', enum] 3941 endforeach 3942 c_bitfields = [ 3943 'ClockEvent', 3944 'VMStateFlags', 3945 ] 3946 foreach enum : c_bitfields 3947 bindgen_args += ['--bitfield-enum', enum] 3948 endforeach 3949 3950 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 3951 # 3952 # Rust bindings generation with `bindgen` might fail in some cases where the 3953 # detected `libclang` does not match the expected `clang` version/target. In 3954 # this case you must pass the path to `clang` and `libclang` to your build 3955 # command invocation using the environment variables CLANG_PATH and 3956 # LIBCLANG_PATH 3957 bindings_rs = import('rust').bindgen( 3958 input: 'rust/wrapper.h', 3959 dependencies: common_ss.all_dependencies(), 3960 output: 'bindings.rs', 3961 include_directories: include_directories('.', 'include'), 3962 bindgen_version: ['>=0.69.4'], 3963 args: bindgen_args, 3964 ) 3965 subdir('rust') 3966endif 3967 3968 3969feature_to_c = find_program('scripts/feature_to_c.py') 3970 3971if host_os == 'darwin' 3972 entitlement = find_program('scripts/entitlement.sh') 3973endif 3974 3975traceable = [] 3976emulators = {} 3977foreach target : target_dirs 3978 config_target = config_target_mak[target] 3979 target_name = config_target['TARGET_NAME'] 3980 target_base_arch = config_target['TARGET_BASE_ARCH'] 3981 arch_srcs = [config_target_h[target]] 3982 arch_deps = [] 3983 c_args = ['-DCOMPILING_PER_TARGET', 3984 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3985 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3986 link_args = emulator_link_args 3987 3988 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3989 if host_os == 'linux' 3990 target_inc += include_directories('linux-headers', is_system: true) 3991 endif 3992 if target.endswith('-softmmu') 3993 target_type='system' 3994 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 3995 arch_srcs += t.sources() 3996 arch_deps += t.dependencies() 3997 3998 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3999 if hw_arch.has_key(hw_dir) 4000 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4001 arch_srcs += hw.sources() 4002 arch_deps += hw.dependencies() 4003 endif 4004 4005 arch_srcs += config_devices_h[target] 4006 link_args += ['@block.syms', '@qemu.syms'] 4007 else 4008 abi = config_target['TARGET_ABI_DIR'] 4009 target_type='user' 4010 target_inc += common_user_inc 4011 if target_base_arch in target_user_arch 4012 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4013 arch_srcs += t.sources() 4014 arch_deps += t.dependencies() 4015 endif 4016 if 'CONFIG_LINUX_USER' in config_target 4017 base_dir = 'linux-user' 4018 endif 4019 if 'CONFIG_BSD_USER' in config_target 4020 base_dir = 'bsd-user' 4021 target_inc += include_directories('bsd-user/' / host_os) 4022 target_inc += include_directories('bsd-user/host/' / host_arch) 4023 dir = base_dir / abi 4024 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4025 endif 4026 target_inc += include_directories( 4027 base_dir, 4028 base_dir / abi, 4029 ) 4030 if 'CONFIG_LINUX_USER' in config_target 4031 dir = base_dir / abi 4032 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4033 if config_target.has_key('TARGET_SYSTBL_ABI') 4034 arch_srcs += \ 4035 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4036 extra_args : config_target['TARGET_SYSTBL_ABI']) 4037 endif 4038 endif 4039 endif 4040 4041 if 'TARGET_XML_FILES' in config_target 4042 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4043 output: target + '-gdbstub-xml.c', 4044 input: files(config_target['TARGET_XML_FILES'].split()), 4045 command: [feature_to_c, '@INPUT@'], 4046 capture: true) 4047 arch_srcs += gdbstub_xml 4048 endif 4049 4050 t = target_arch[target_base_arch].apply(config_target, strict: false) 4051 arch_srcs += t.sources() 4052 arch_deps += t.dependencies() 4053 4054 target_common = common_ss.apply(config_target, strict: false) 4055 objects = common_all.extract_objects(target_common.sources()) 4056 arch_deps += target_common.dependencies() 4057 4058 target_specific = specific_ss.apply(config_target, strict: false) 4059 arch_srcs += target_specific.sources() 4060 arch_deps += target_specific.dependencies() 4061 4062 # allow using headers from the dependencies but do not include the sources, 4063 # because this emulator only needs those in "objects". For external 4064 # dependencies, the full dependency is included below in the executable. 4065 lib_deps = [] 4066 foreach dep : arch_deps 4067 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4068 endforeach 4069 4070 lib = static_library('qemu-' + target, 4071 sources: arch_srcs + genh, 4072 dependencies: lib_deps, 4073 objects: objects, 4074 include_directories: target_inc, 4075 c_args: c_args, 4076 build_by_default: false) 4077 4078 if target.endswith('-softmmu') 4079 execs = [{ 4080 'name': 'qemu-system-' + target_name, 4081 'win_subsystem': 'console', 4082 'sources': files('system/main.c'), 4083 'dependencies': [] 4084 }] 4085 if host_os == 'windows' and (sdl.found() or gtk.found()) 4086 execs += [{ 4087 'name': 'qemu-system-' + target_name + 'w', 4088 'win_subsystem': 'windows', 4089 'sources': files('system/main.c'), 4090 'dependencies': [] 4091 }] 4092 endif 4093 if get_option('fuzzing') 4094 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4095 execs += [{ 4096 'name': 'qemu-fuzz-' + target_name, 4097 'win_subsystem': 'console', 4098 'sources': specific_fuzz.sources(), 4099 'dependencies': specific_fuzz.dependencies(), 4100 }] 4101 endif 4102 else 4103 execs = [{ 4104 'name': 'qemu-' + target_name, 4105 'win_subsystem': 'console', 4106 'sources': [], 4107 'dependencies': [] 4108 }] 4109 endif 4110 foreach exe: execs 4111 exe_name = exe['name'] 4112 if host_os == 'darwin' 4113 exe_name += '-unsigned' 4114 endif 4115 4116 emulator = executable(exe_name, exe['sources'], 4117 install: true, 4118 c_args: c_args, 4119 dependencies: arch_deps + exe['dependencies'], 4120 objects: lib.extract_all_objects(recursive: true), 4121 link_depends: [block_syms, qemu_syms], 4122 link_args: link_args, 4123 win_subsystem: exe['win_subsystem']) 4124 4125 if host_os == 'darwin' 4126 icon = 'pc-bios/qemu.rsrc' 4127 build_input = [emulator, files(icon)] 4128 install_input = [ 4129 get_option('bindir') / exe_name, 4130 meson.current_source_dir() / icon 4131 ] 4132 if 'CONFIG_HVF' in config_target 4133 entitlements = 'accel/hvf/entitlements.plist' 4134 build_input += files(entitlements) 4135 install_input += meson.current_source_dir() / entitlements 4136 endif 4137 4138 emulators += {exe['name'] : custom_target(exe['name'], 4139 input: build_input, 4140 output: exe['name'], 4141 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4142 } 4143 4144 meson.add_install_script(entitlement, '--install', 4145 get_option('bindir') / exe['name'], 4146 install_input) 4147 else 4148 emulators += {exe['name']: emulator} 4149 endif 4150 4151 traceable += [{ 4152 'exe': exe['name'], 4153 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4154 }] 4155 4156 endforeach 4157endforeach 4158 4159# Other build targets 4160 4161if get_option('plugins') 4162 install_headers('include/qemu/qemu-plugin.h') 4163 if host_os == 'windows' 4164 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4165 # so that plugin authors can compile against it. 4166 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4167 endif 4168endif 4169 4170subdir('qga') 4171 4172# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4173# when we don't build tools or system 4174if xkbcommon.found() 4175 # used for the update-keymaps target, so include rules even if !have_tools 4176 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4177 dependencies: [qemuutil, xkbcommon], install: have_tools) 4178endif 4179 4180if have_tools 4181 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4182 link_args: '@block.syms', link_depends: block_syms, 4183 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4184 qemu_io = executable('qemu-io', files('qemu-io.c'), 4185 link_args: '@block.syms', link_depends: block_syms, 4186 dependencies: [block, qemuutil], install: true) 4187 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4188 link_args: '@block.syms', link_depends: block_syms, 4189 dependencies: [blockdev, qemuutil, selinux], 4190 install: true) 4191 4192 subdir('storage-daemon') 4193 4194 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4195 traceable += [{ 4196 'exe': exe, 4197 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4198 }] 4199 endforeach 4200 4201 subdir('contrib/elf2dmp') 4202 4203 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4204 dependencies: qemuutil, 4205 install: true) 4206 4207 if have_vhost_user 4208 subdir('contrib/vhost-user-blk') 4209 subdir('contrib/vhost-user-gpu') 4210 subdir('contrib/vhost-user-input') 4211 subdir('contrib/vhost-user-scsi') 4212 endif 4213 4214 if host_os == 'linux' 4215 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4216 dependencies: [qemuutil, libcap_ng], 4217 install: true, 4218 install_dir: get_option('libexecdir')) 4219 4220 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4221 dependencies: [authz, crypto, io, qom, qemuutil, 4222 libcap_ng, mpathpersist], 4223 install: true) 4224 4225 if cpu in ['x86', 'x86_64'] 4226 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4227 dependencies: [authz, crypto, io, qom, qemuutil, 4228 libcap_ng, mpathpersist], 4229 install: true) 4230 endif 4231 endif 4232 4233 if have_ivshmem 4234 subdir('contrib/ivshmem-client') 4235 subdir('contrib/ivshmem-server') 4236 endif 4237endif 4238 4239if stap.found() 4240 foreach t: traceable 4241 foreach stp: [ 4242 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4243 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4244 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4245 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4246 ] 4247 cmd = [ 4248 tracetool, '--group=all', '--format=' + stp['fmt'], 4249 '--binary=' + stp['bin'], 4250 '--probe-prefix=' + t['probe-prefix'], 4251 '@INPUT@', '@OUTPUT@' 4252 ] 4253 4254 custom_target(t['exe'] + stp['ext'], 4255 input: trace_events_all, 4256 output: t['exe'] + stp['ext'], 4257 install: stp['install'], 4258 install_dir: get_option('datadir') / 'systemtap/tapset', 4259 command: cmd, 4260 depend_files: tracetool_depends) 4261 endforeach 4262 endforeach 4263endif 4264 4265subdir('scripts') 4266subdir('tools') 4267subdir('pc-bios') 4268subdir('docs') 4269subdir('tests') 4270if gtk.found() 4271 subdir('po') 4272endif 4273 4274if host_machine.system() == 'windows' 4275 nsis_cmd = [ 4276 find_program('scripts/nsis.py'), 4277 '@OUTPUT@', 4278 get_option('prefix'), 4279 meson.current_source_dir(), 4280 glib_pc.get_variable('bindir'), 4281 host_machine.cpu(), 4282 '--', 4283 '-DDISPLAYVERSION=' + meson.project_version(), 4284 ] 4285 if build_docs 4286 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4287 endif 4288 if gtk.found() 4289 nsis_cmd += '-DCONFIG_GTK=y' 4290 endif 4291 4292 nsis = custom_target('nsis', 4293 output: 'qemu-setup-' + meson.project_version() + '.exe', 4294 input: files('qemu.nsi'), 4295 build_always_stale: true, 4296 command: nsis_cmd + ['@INPUT@']) 4297 alias_target('installer', nsis) 4298endif 4299 4300######################### 4301# Configuration summary # 4302######################### 4303 4304# Build environment 4305summary_info = {} 4306summary_info += {'Build directory': meson.current_build_dir()} 4307summary_info += {'Source path': meson.current_source_dir()} 4308summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4309summary(summary_info, bool_yn: true, section: 'Build environment') 4310 4311# Directories 4312summary_info += {'Install prefix': get_option('prefix')} 4313summary_info += {'BIOS directory': qemu_datadir} 4314pathsep = host_os == 'windows' ? ';' : ':' 4315summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4316summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4317summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4318summary_info += {'module directory': qemu_moddir} 4319summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4320summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4321summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4322if host_os != 'windows' 4323 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4324 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4325else 4326 summary_info += {'local state directory': 'queried at runtime'} 4327endif 4328summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4329summary(summary_info, bool_yn: true, section: 'Directories') 4330 4331# Host binaries 4332summary_info = {} 4333summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4334summary_info += {'sphinx-build': sphinx_build} 4335 4336# FIXME: the [binaries] section of machine files, which can be probed 4337# with find_program(), would be great for passing gdb and genisoimage 4338# paths from configure to Meson. However, there seems to be no way to 4339# hide a program (for example if gdb is too old). 4340if config_host.has_key('GDB') 4341 summary_info += {'gdb': config_host['GDB']} 4342endif 4343summary_info += {'iasl': iasl} 4344summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4345if host_os == 'windows' and have_ga 4346 summary_info += {'wixl': wixl} 4347endif 4348if slirp.found() and have_system 4349 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4350endif 4351summary(summary_info, bool_yn: true, section: 'Host binaries') 4352 4353# Configurable features 4354summary_info = {} 4355summary_info += {'Documentation': build_docs} 4356summary_info += {'system-mode emulation': have_system} 4357summary_info += {'user-mode emulation': have_user} 4358summary_info += {'block layer': have_block} 4359summary_info += {'Install blobs': get_option('install_blobs')} 4360summary_info += {'module support': enable_modules} 4361if enable_modules 4362 summary_info += {'alternative module path': get_option('module_upgrades')} 4363endif 4364summary_info += {'fuzzing support': get_option('fuzzing')} 4365if have_system 4366 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4367endif 4368summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4369if 'simple' in get_option('trace_backends') 4370 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4371endif 4372summary_info += {'D-Bus display': dbus_display} 4373summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4374summary_info += {'Relocatable install': get_option('relocatable')} 4375summary_info += {'vhost-kernel support': have_vhost_kernel} 4376summary_info += {'vhost-net support': have_vhost_net} 4377summary_info += {'vhost-user support': have_vhost_user} 4378summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4379summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4380summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4381summary_info += {'build guest agent': have_ga} 4382summary(summary_info, bool_yn: true, section: 'Configurable features') 4383 4384# Compilation information 4385summary_info = {} 4386summary_info += {'host CPU': cpu} 4387summary_info += {'host endianness': build_machine.endian()} 4388summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4389summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4390if 'cpp' in all_languages 4391 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4392else 4393 summary_info += {'C++ compiler': false} 4394endif 4395if 'objc' in all_languages 4396 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4397else 4398 summary_info += {'Objective-C compiler': false} 4399endif 4400summary_info += {'Rust support': have_rust} 4401if have_rust 4402 summary_info += {'rustc version': rustc.version()} 4403 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4404 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4405endif 4406option_cflags = (get_option('debug') ? ['-g'] : []) 4407if get_option('optimization') != 'plain' 4408 option_cflags += ['-O' + get_option('optimization')] 4409endif 4410summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4411if 'cpp' in all_languages 4412 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4413endif 4414if 'objc' in all_languages 4415 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4416endif 4417link_args = get_option('c_link_args') 4418if link_args.length() > 0 4419 summary_info += {'LDFLAGS': ' '.join(link_args)} 4420endif 4421summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4422if 'cpp' in all_languages 4423 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4424endif 4425if 'objc' in all_languages 4426 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4427endif 4428summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4429summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4430summary_info += {'PIE': get_option('b_pie')} 4431summary_info += {'static build': get_option('prefer_static')} 4432summary_info += {'malloc trim support': has_malloc_trim} 4433summary_info += {'membarrier': have_membarrier} 4434summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4435summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4436summary_info += {'mutex debugging': get_option('debug_mutex')} 4437summary_info += {'memory allocator': get_option('malloc')} 4438summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4439summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4440summary_info += {'gcov': get_option('b_coverage')} 4441summary_info += {'thread sanitizer': get_option('tsan')} 4442summary_info += {'CFI support': get_option('cfi')} 4443if get_option('cfi') 4444 summary_info += {'CFI debug support': get_option('cfi_debug')} 4445endif 4446summary_info += {'strip binaries': get_option('strip')} 4447summary_info += {'sparse': sparse} 4448summary_info += {'mingw32 support': host_os == 'windows'} 4449summary(summary_info, bool_yn: true, section: 'Compilation') 4450 4451# snarf the cross-compilation information for tests 4452summary_info = {} 4453have_cross = false 4454foreach target: target_dirs 4455 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4456 if fs.exists(tcg_mak) 4457 config_cross_tcg = keyval.load(tcg_mak) 4458 if 'CC' in config_cross_tcg 4459 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4460 have_cross = true 4461 endif 4462 endif 4463endforeach 4464if have_cross 4465 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4466endif 4467 4468# Targets and accelerators 4469summary_info = {} 4470if have_system 4471 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4472 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4473 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4474 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4475 summary_info += {'Xen support': xen.found()} 4476 if xen.found() 4477 summary_info += {'xen ctrl version': xen.version()} 4478 endif 4479 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4480endif 4481summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4482if config_all_accel.has_key('CONFIG_TCG') 4483 if get_option('tcg_interpreter') 4484 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4485 else 4486 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4487 endif 4488 summary_info += {'TCG plugins': get_option('plugins')} 4489 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4490 if have_linux_user or have_bsd_user 4491 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4492 endif 4493endif 4494summary_info += {'target list': ' '.join(target_dirs)} 4495if have_system 4496 summary_info += {'default devices': get_option('default_devices')} 4497 summary_info += {'out of process emulation': multiprocess_allowed} 4498 summary_info += {'vfio-user server': vfio_user_server_allowed} 4499endif 4500summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4501 4502# Block layer 4503summary_info = {} 4504summary_info += {'coroutine backend': coroutine_backend} 4505summary_info += {'coroutine pool': have_coroutine_pool} 4506if have_block 4507 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4508 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4509 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4510 summary_info += {'VirtFS (9P) support': have_virtfs} 4511 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4512 summary_info += {'bochs support': get_option('bochs').allowed()} 4513 summary_info += {'cloop support': get_option('cloop').allowed()} 4514 summary_info += {'dmg support': get_option('dmg').allowed()} 4515 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4516 summary_info += {'vdi support': get_option('vdi').allowed()} 4517 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4518 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4519 summary_info += {'vpc support': get_option('vpc').allowed()} 4520 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4521 summary_info += {'qed support': get_option('qed').allowed()} 4522 summary_info += {'parallels support': get_option('parallels').allowed()} 4523 summary_info += {'FUSE exports': fuse} 4524 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4525endif 4526summary(summary_info, bool_yn: true, section: 'Block layer support') 4527 4528# Crypto 4529summary_info = {} 4530summary_info += {'TLS priority': get_option('tls_priority')} 4531summary_info += {'GNUTLS support': gnutls} 4532if gnutls.found() 4533 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4534endif 4535summary_info += {'libgcrypt': gcrypt} 4536summary_info += {'nettle': nettle} 4537if nettle.found() 4538 summary_info += {' XTS': xts != 'private'} 4539endif 4540summary_info += {'SM4 ALG support': crypto_sm4} 4541summary_info += {'AF_ALG support': have_afalg} 4542summary_info += {'rng-none': get_option('rng_none')} 4543summary_info += {'Linux keyring': have_keyring} 4544summary_info += {'Linux keyutils': keyutils} 4545summary(summary_info, bool_yn: true, section: 'Crypto') 4546 4547# UI 4548summary_info = {} 4549if host_os == 'darwin' 4550 summary_info += {'Cocoa support': cocoa} 4551endif 4552summary_info += {'SDL support': sdl} 4553summary_info += {'SDL image support': sdl_image} 4554summary_info += {'GTK support': gtk} 4555summary_info += {'pixman': pixman} 4556summary_info += {'VTE support': vte} 4557summary_info += {'PNG support': png} 4558summary_info += {'VNC support': vnc} 4559if vnc.found() 4560 summary_info += {'VNC SASL support': sasl} 4561 summary_info += {'VNC JPEG support': jpeg} 4562endif 4563summary_info += {'spice protocol support': spice_protocol} 4564if spice_protocol.found() 4565 summary_info += {' spice server support': spice} 4566endif 4567summary_info += {'curses support': curses} 4568summary_info += {'brlapi support': brlapi} 4569summary(summary_info, bool_yn: true, section: 'User interface') 4570 4571# Graphics backends 4572summary_info = {} 4573summary_info += {'VirGL support': virgl} 4574summary_info += {'Rutabaga support': rutabaga} 4575summary(summary_info, bool_yn: true, section: 'Graphics backends') 4576 4577# Audio backends 4578summary_info = {} 4579if host_os not in ['darwin', 'haiku', 'windows'] 4580 summary_info += {'OSS support': oss} 4581 summary_info += {'sndio support': sndio} 4582elif host_os == 'darwin' 4583 summary_info += {'CoreAudio support': coreaudio} 4584elif host_os == 'windows' 4585 summary_info += {'DirectSound support': dsound} 4586endif 4587if host_os == 'linux' 4588 summary_info += {'ALSA support': alsa} 4589 summary_info += {'PulseAudio support': pulse} 4590endif 4591summary_info += {'PipeWire support': pipewire} 4592summary_info += {'JACK support': jack} 4593summary(summary_info, bool_yn: true, section: 'Audio backends') 4594 4595# Network backends 4596summary_info = {} 4597if host_os == 'darwin' 4598 summary_info += {'vmnet.framework support': vmnet} 4599endif 4600summary_info += {'AF_XDP support': libxdp} 4601summary_info += {'slirp support': slirp} 4602summary_info += {'vde support': vde} 4603summary_info += {'netmap support': have_netmap} 4604summary_info += {'l2tpv3 support': have_l2tpv3} 4605summary(summary_info, bool_yn: true, section: 'Network backends') 4606 4607# Libraries 4608summary_info = {} 4609summary_info += {'libtasn1': tasn1} 4610summary_info += {'PAM': pam} 4611summary_info += {'iconv support': iconv} 4612summary_info += {'blkio support': blkio} 4613summary_info += {'curl support': curl} 4614summary_info += {'Multipath support': mpathpersist} 4615summary_info += {'Linux AIO support': libaio} 4616summary_info += {'Linux io_uring support': linux_io_uring} 4617summary_info += {'ATTR/XATTR support': libattr} 4618summary_info += {'RDMA support': rdma} 4619summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4620summary_info += {'libcap-ng support': libcap_ng} 4621summary_info += {'bpf support': libbpf} 4622summary_info += {'rbd support': rbd} 4623summary_info += {'smartcard support': cacard} 4624summary_info += {'U2F support': u2f} 4625summary_info += {'libusb': libusb} 4626summary_info += {'usb net redir': usbredir} 4627summary_info += {'OpenGL support (epoxy)': opengl} 4628summary_info += {'GBM': gbm} 4629summary_info += {'libiscsi support': libiscsi} 4630summary_info += {'libnfs support': libnfs} 4631if host_os == 'windows' 4632 if have_ga 4633 summary_info += {'QGA VSS support': have_qga_vss} 4634 endif 4635endif 4636summary_info += {'seccomp support': seccomp} 4637summary_info += {'GlusterFS support': glusterfs} 4638summary_info += {'hv-balloon support': hv_balloon} 4639summary_info += {'TPM support': have_tpm} 4640summary_info += {'libssh support': libssh} 4641summary_info += {'lzo support': lzo} 4642summary_info += {'snappy support': snappy} 4643summary_info += {'bzip2 support': libbzip2} 4644summary_info += {'lzfse support': liblzfse} 4645summary_info += {'zstd support': zstd} 4646summary_info += {'Query Processing Library support': qpl} 4647summary_info += {'UADK Library support': uadk} 4648summary_info += {'qatzip support': qatzip} 4649summary_info += {'NUMA host support': numa} 4650summary_info += {'capstone': capstone} 4651summary_info += {'libpmem support': libpmem} 4652summary_info += {'libdaxctl support': libdaxctl} 4653summary_info += {'libudev': libudev} 4654# Dummy dependency, keep .found() 4655summary_info += {'FUSE lseek': fuse_lseek.found()} 4656summary_info += {'selinux': selinux} 4657summary_info += {'libdw': libdw} 4658if host_os == 'freebsd' 4659 summary_info += {'libinotify-kqueue': inotify} 4660endif 4661summary(summary_info, bool_yn: true, section: 'Dependencies') 4662 4663if host_arch == 'unknown' 4664 message() 4665 warning('UNSUPPORTED HOST CPU') 4666 message() 4667 message('Support for CPU host architecture ' + cpu + ' is not currently') 4668 message('maintained. The QEMU project does not guarantee that QEMU will') 4669 message('compile or work on this host CPU. You can help by volunteering') 4670 message('to maintain it and providing a build host for our continuous') 4671 message('integration setup.') 4672 if get_option('tcg').allowed() and target_dirs.length() > 0 4673 message() 4674 message('configure has succeeded and you can continue to build, but') 4675 message('QEMU will use a slow interpreter to emulate the target CPU.') 4676 endif 4677endif 4678 4679if not supported_oses.contains(host_os) 4680 message() 4681 warning('UNSUPPORTED HOST OS') 4682 message() 4683 message('Support for host OS ' + host_os + 'is not currently maintained.') 4684 message('configure has succeeded and you can continue to build, but') 4685 message('the QEMU project does not guarantee that QEMU will compile or') 4686 message('work on this operating system. You can help by volunteering') 4687 message('to maintain it and providing a build host for our continuous') 4688 message('integration setup. This will ensure that future versions of QEMU') 4689 message('will keep working on ' + host_os + '.') 4690endif 4691 4692if host_arch == 'unknown' or not supported_oses.contains(host_os) 4693 message() 4694 message('If you want to help supporting QEMU on this platform, please') 4695 message('contact the developers at qemu-devel@nongnu.org.') 4696endif 4697 4698actually_reloc = get_option('relocatable') 4699# check if get_relocated_path() is actually able to relocate paths 4700if get_option('relocatable') and \ 4701 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4702 message() 4703 warning('bindir not included within prefix, the installation will not be relocatable.') 4704 actually_reloc = false 4705endif 4706if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4707 if host_os == 'windows' 4708 message() 4709 warning('Windows installs should usually be relocatable.') 4710 endif 4711 message() 4712 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4713 message('Use --disable-relocatable to remove this warning.') 4714endif 4715