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