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