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