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