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 2888have_l2tpv3 = false 2889if get_option('l2tpv3').allowed() and have_system 2890 have_l2tpv3 = cc.has_type('struct mmsghdr', 2891 prefix: gnu_source_prefix + ''' 2892 #include <sys/socket.h> 2893 #include <linux/ip.h>''') 2894endif 2895config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2896 2897have_netmap = false 2898if get_option('netmap').allowed() and have_system 2899 have_netmap = cc.compiles(''' 2900 #include <inttypes.h> 2901 #include <net/if.h> 2902 #include <net/netmap.h> 2903 #include <net/netmap_user.h> 2904 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2905 #error 2906 #endif 2907 int main(void) { return 0; }''') 2908 if not have_netmap and get_option('netmap').enabled() 2909 error('Netmap headers not available') 2910 endif 2911endif 2912config_host_data.set('CONFIG_NETMAP', have_netmap) 2913 2914# Work around a system header bug with some kernel/XFS header 2915# versions where they both try to define 'struct fsxattr': 2916# xfs headers will not try to redefine structs from linux headers 2917# if this macro is set. 2918config_host_data.set('HAVE_FSXATTR', cc.links(''' 2919 #include <linux/fs.h> 2920 struct fsxattr foo; 2921 int main(void) { 2922 return 0; 2923 }''')) 2924 2925# Some versions of Mac OS X incorrectly define SIZE_MAX 2926config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2927 #include <stdint.h> 2928 #include <stdio.h> 2929 int main(void) { 2930 return printf("%zu", SIZE_MAX); 2931 }''', args: ['-Werror'])) 2932 2933# See if 64-bit atomic operations are supported. 2934# Note that without __atomic builtins, we can only 2935# assume atomic loads/stores max at pointer size. 2936config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 2937 #include <stdint.h> 2938 int main(void) 2939 { 2940 uint64_t x = 0, y = 0; 2941 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 2942 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 2943 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2944 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 2945 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 2946 return 0; 2947 }''', args: qemu_isa_flags)) 2948 2949has_int128_type = cc.compiles(''' 2950 __int128_t a; 2951 __uint128_t b; 2952 int main(void) { b = a; }''') 2953config_host_data.set('CONFIG_INT128_TYPE', has_int128_type) 2954 2955has_int128 = has_int128_type and cc.links(''' 2956 __int128_t a; 2957 __uint128_t b; 2958 int main (void) { 2959 a = a + b; 2960 b = a * b; 2961 a = a * a; 2962 return 0; 2963 }''') 2964config_host_data.set('CONFIG_INT128', has_int128) 2965 2966if has_int128_type 2967 # "do we have 128-bit atomics which are handled inline and specifically not 2968 # via libatomic". The reason we can't use libatomic is documented in the 2969 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 2970 # We only care about these operations on 16-byte aligned pointers, so 2971 # force 16-byte alignment of the pointer, which may be greater than 2972 # __alignof(unsigned __int128) for the host. 2973 atomic_test_128 = ''' 2974 int main(int ac, char **av) { 2975 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16); 2976 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED); 2977 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED); 2978 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2979 return 0; 2980 }''' 2981 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags) 2982 2983 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 2984 2985 if not has_atomic128 2986 # Even with __builtin_assume_aligned, the above test may have failed 2987 # without optimization enabled. Try again with optimizations locally 2988 # enabled for the function. See 2989 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389 2990 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128, 2991 args: qemu_isa_flags) 2992 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt) 2993 2994 if not has_atomic128_opt 2995 config_host_data.set('CONFIG_CMPXCHG128', cc.links(''' 2996 int main(void) 2997 { 2998 __uint128_t x = 0, y = 0; 2999 __sync_val_compare_and_swap_16(&x, y, x); 3000 return 0; 3001 } 3002 ''', args: qemu_isa_flags)) 3003 endif 3004 endif 3005endif 3006 3007config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 3008 #include <sys/auxv.h> 3009 int main(void) { 3010 return getauxval(AT_HWCAP) == 0; 3011 }''')) 3012 3013config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + ''' 3014 #include <sys/auxv.h> 3015 int main(void) { 3016 unsigned long hwcap = 0; 3017 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); 3018 return hwcap; 3019 }''')) 3020 3021config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 3022 #include <linux/usbdevice_fs.h> 3023 3024 #ifndef USBDEVFS_GET_CAPABILITIES 3025 #error "USBDEVFS_GET_CAPABILITIES undefined" 3026 #endif 3027 3028 #ifndef USBDEVFS_DISCONNECT_CLAIM 3029 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 3030 #endif 3031 3032 int main(void) { return 0; }''')) 3033 3034have_keyring = get_option('keyring') \ 3035 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \ 3036 .require(cc.compiles(''' 3037 #include <errno.h> 3038 #include <asm/unistd.h> 3039 #include <linux/keyctl.h> 3040 #include <sys/syscall.h> 3041 #include <unistd.h> 3042 int main(void) { 3043 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 3044 }'''), error_message: 'keyctl syscall not available on this system').allowed() 3045config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 3046 3047have_cpuid_h = cc.links(''' 3048 #include <cpuid.h> 3049 int main(void) { 3050 unsigned a, b, c, d; 3051 unsigned max = __get_cpuid_max(0, 0); 3052 3053 if (max >= 1) { 3054 __cpuid(1, a, b, c, d); 3055 } 3056 3057 if (max >= 7) { 3058 __cpuid_count(7, 0, a, b, c, d); 3059 } 3060 3061 return 0; 3062 }''') 3063config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 3064 3065# Don't bother to advertise asm/hwprobe.h for old versions that do 3066# not contain RISCV_HWPROBE_EXT_ZBA. 3067config_host_data.set('CONFIG_ASM_HWPROBE_H', 3068 cc.has_header_symbol('asm/hwprobe.h', 3069 'RISCV_HWPROBE_EXT_ZBA')) 3070 3071config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 3072 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 3073 .require(cc.links(''' 3074 #include <cpuid.h> 3075 #include <immintrin.h> 3076 static int __attribute__((target("avx2"))) bar(void *a) { 3077 __m256i x = *(__m256i *)a; 3078 return _mm256_testz_si256(x, x); 3079 } 3080 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 3081 '''), error_message: 'AVX2 not available').allowed()) 3082 3083config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \ 3084 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \ 3085 .require(cc.links(''' 3086 #include <cpuid.h> 3087 #include <immintrin.h> 3088 static int __attribute__((target("avx512bw"))) bar(void *a) { 3089 __m512i *x = a; 3090 __m512i res= _mm512_abs_epi8(*x); 3091 return res[1]; 3092 } 3093 int main(int argc, char *argv[]) { return bar(argv[0]); } 3094 '''), error_message: 'AVX512BW not available').allowed()) 3095 3096# For both AArch64 and AArch32, detect if builtins are available. 3097config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles(''' 3098 #include <arm_neon.h> 3099 #ifndef __ARM_FEATURE_AES 3100 __attribute__((target("+crypto"))) 3101 #endif 3102 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); } 3103 ''')) 3104 3105if get_option('membarrier').disabled() 3106 have_membarrier = false 3107elif host_os == 'windows' 3108 have_membarrier = true 3109elif host_os == 'linux' 3110 have_membarrier = cc.compiles(''' 3111 #include <linux/membarrier.h> 3112 #include <sys/syscall.h> 3113 #include <unistd.h> 3114 #include <stdlib.h> 3115 int main(void) { 3116 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 3117 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 3118 exit(0); 3119 }''') 3120endif 3121config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 3122 .require(have_membarrier, error_message: 'membarrier system call not available') \ 3123 .allowed()) 3124 3125have_afalg = get_option('crypto_afalg') \ 3126 .require(cc.compiles(gnu_source_prefix + ''' 3127 #include <errno.h> 3128 #include <sys/types.h> 3129 #include <sys/socket.h> 3130 #include <linux/if_alg.h> 3131 int main(void) { 3132 int sock; 3133 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 3134 return sock; 3135 } 3136 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 3137config_host_data.set('CONFIG_AF_ALG', have_afalg) 3138 3139config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 3140 'linux/vm_sockets.h', 'AF_VSOCK', 3141 prefix: '#include <sys/socket.h>', 3142)) 3143 3144have_vss = false 3145have_vss_sdk = false # old xp/2003 SDK 3146if host_os == 'windows' and 'cpp' in all_languages 3147 have_vss = cxx.compiles(''' 3148 #define __MIDL_user_allocate_free_DEFINED__ 3149 #include <vss.h> 3150 int main(void) { return VSS_CTX_BACKUP; }''') 3151 have_vss_sdk = cxx.has_header('vscoordint.h') 3152endif 3153config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 3154 3155# Older versions of MinGW do not import _lock_file and _unlock_file properly. 3156# This was fixed for v6.0.0 with commit b48e3ac8969d. 3157if host_os == 'windows' 3158 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 3159 #include <stdio.h> 3160 int main(void) { 3161 _lock_file(NULL); 3162 _unlock_file(NULL); 3163 return 0; 3164 }''', name: '_lock_file and _unlock_file')) 3165endif 3166 3167if host_os == 'windows' 3168 mingw_has_setjmp_longjmp = cc.links(''' 3169 #include <setjmp.h> 3170 int main(void) { 3171 /* 3172 * These functions are not available in setjmp header, but may be 3173 * available at link time, from libmingwex.a. 3174 */ 3175 extern int __mingw_setjmp(jmp_buf); 3176 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int); 3177 jmp_buf env; 3178 __mingw_setjmp(env); 3179 __mingw_longjmp(env, 0); 3180 } 3181 ''', name: 'mingw setjmp and longjmp') 3182 3183 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp 3184 error('mingw must provide setjmp/longjmp for windows-arm64') 3185 endif 3186endif 3187 3188# Detect host pointer size for the target configuration loop. 3189host_long_bits = cc.sizeof('void *') * 8 3190 3191######################## 3192# Target configuration # 3193######################## 3194 3195minikconf = find_program('scripts/minikconf.py') 3196 3197config_all_accel = {} 3198config_all_devices = {} 3199config_devices_mak_list = [] 3200config_devices_h = {} 3201config_target_h = {} 3202config_target_mak = {} 3203 3204disassemblers = { 3205 'alpha' : ['CONFIG_ALPHA_DIS'], 3206 'avr' : ['CONFIG_AVR_DIS'], 3207 'hexagon' : ['CONFIG_HEXAGON_DIS'], 3208 'hppa' : ['CONFIG_HPPA_DIS'], 3209 'i386' : ['CONFIG_I386_DIS'], 3210 'x86_64' : ['CONFIG_I386_DIS'], 3211 'm68k' : ['CONFIG_M68K_DIS'], 3212 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 3213 'mips' : ['CONFIG_MIPS_DIS'], 3214 'or1k' : ['CONFIG_OPENRISC_DIS'], 3215 'ppc' : ['CONFIG_PPC_DIS'], 3216 'riscv' : ['CONFIG_RISCV_DIS'], 3217 'rx' : ['CONFIG_RX_DIS'], 3218 's390' : ['CONFIG_S390_DIS'], 3219 'sh4' : ['CONFIG_SH4_DIS'], 3220 'sparc' : ['CONFIG_SPARC_DIS'], 3221 'xtensa' : ['CONFIG_XTENSA_DIS'], 3222 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 3223} 3224 3225have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 3226host_kconfig = \ 3227 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 3228 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 3229 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ 3230 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 3231 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 3232 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 3233 (libcbor.found() ? ['CONFIG_LIBCBOR=y'] : []) + \ 3234 (gnutls.found() ? ['CONFIG_GNUTLS=y'] : []) + \ 3235 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 3236 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \ 3237 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 3238 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 3239 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 3240 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 3241 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \ 3242 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 3243 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \ 3244 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \ 3245 (have_rust ? ['CONFIG_HAVE_RUST=y'] : []) 3246 3247ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 3248 3249default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 3250actual_target_dirs = [] 3251fdt_required = [] 3252foreach target : target_dirs 3253 config_target = { 'TARGET_NAME': target.split('-')[0] } 3254 if target.endswith('linux-user') 3255 if host_os != 'linux' 3256 if default_targets 3257 continue 3258 endif 3259 error('Target @0@ is only available on a Linux host'.format(target)) 3260 endif 3261 config_target += { 'CONFIG_LINUX_USER': 'y' } 3262 elif target.endswith('bsd-user') 3263 if host_os not in bsd_oses 3264 if default_targets 3265 continue 3266 endif 3267 error('Target @0@ is only available on a BSD host'.format(target)) 3268 endif 3269 config_target += { 'CONFIG_BSD_USER': 'y' } 3270 elif target.endswith('softmmu') 3271 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' } 3272 config_target += { 'CONFIG_SOFTMMU': 'y' } 3273 endif 3274 if target.endswith('-user') 3275 config_target += { 3276 'CONFIG_USER_ONLY': 'y', 3277 'CONFIG_QEMU_INTERP_PREFIX': 3278 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']), 3279 'CONFIG_QEMU_RTSIG_MAP': get_option('rtsig_map'), 3280 } 3281 endif 3282 3283 config_target += keyval.load('configs/targets' / target + '.mak') 3284 3285 target_kconfig = [] 3286 foreach sym: accelerators 3287 # Disallow 64-bit on 32-bit emulation and virtualization 3288 if host_long_bits < config_target['TARGET_LONG_BITS'].to_int() 3289 continue 3290 endif 3291 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 3292 config_target += { sym: 'y' } 3293 config_all_accel += { sym: 'y' } 3294 target_kconfig += [ sym + '=y' ] 3295 endif 3296 endforeach 3297 if target_kconfig.length() == 0 3298 if default_targets 3299 continue 3300 endif 3301 error('No accelerator available for target @0@'.format(target)) 3302 endif 3303 3304 if 'TARGET_NEED_FDT' in config_target and not fdt.found() 3305 if default_targets 3306 warning('Disabling ' + target + ' due to missing libfdt') 3307 else 3308 fdt_required += target 3309 endif 3310 continue 3311 endif 3312 3313 actual_target_dirs += target 3314 3315 # Add default keys 3316 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 3317 if 'TARGET_BASE_ARCH' not in config_target 3318 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 3319 endif 3320 if 'TARGET_ABI_DIR' not in config_target 3321 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 3322 endif 3323 if 'TARGET_BIG_ENDIAN' not in config_target 3324 config_target += {'TARGET_BIG_ENDIAN': 'n'} 3325 endif 3326 3327 foreach k, v: disassemblers 3328 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 3329 foreach sym: v 3330 config_target += { sym: 'y' } 3331 endforeach 3332 endif 3333 endforeach 3334 3335 config_target_data = configuration_data() 3336 foreach k, v: config_target 3337 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 3338 # do nothing 3339 elif ignored.contains(k) 3340 # do nothing 3341 elif k == 'TARGET_BASE_ARCH' 3342 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 3343 # not used to select files from sourcesets. 3344 config_target_data.set('TARGET_' + v.to_upper(), 1) 3345 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 3346 config_target_data.set_quoted(k, v) 3347 elif v == 'y' 3348 config_target_data.set(k, 1) 3349 elif v == 'n' 3350 config_target_data.set(k, 0) 3351 else 3352 config_target_data.set(k, v) 3353 endif 3354 endforeach 3355 config_target_data.set('QEMU_ARCH', 3356 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 3357 config_target_h += {target: configure_file(output: target + '-config-target.h', 3358 configuration: config_target_data)} 3359 3360 if target.endswith('-softmmu') 3361 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y' 3362 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN'] 3363 3364 config_input = meson.get_external_property(target, 'default') 3365 config_devices_mak = target + '-config-devices.mak' 3366 config_devices_mak = configure_file( 3367 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 3368 output: config_devices_mak, 3369 depfile: config_devices_mak + '.d', 3370 capture: true, 3371 command: [minikconf, 3372 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 3373 config_devices_mak, '@DEPFILE@', '@INPUT@', 3374 host_kconfig, target_kconfig]) 3375 3376 config_devices_data = configuration_data() 3377 config_devices = keyval.load(config_devices_mak) 3378 foreach k, v: config_devices 3379 config_devices_data.set(k, 1) 3380 endforeach 3381 config_devices_mak_list += config_devices_mak 3382 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 3383 configuration: config_devices_data)} 3384 config_target += config_devices 3385 config_all_devices += config_devices 3386 endif 3387 config_target_mak += {target: config_target} 3388endforeach 3389target_dirs = actual_target_dirs 3390 3391target_configs_h = [] 3392foreach target: target_dirs 3393 target_configs_h += config_target_h[target] 3394 target_configs_h += config_devices_h.get(target, []) 3395endforeach 3396genh += custom_target('config-poison.h', 3397 input: [target_configs_h], 3398 output: 'config-poison.h', 3399 capture: true, 3400 command: [find_program('scripts/make-config-poison.sh'), 3401 target_configs_h]) 3402 3403if fdt_required.length() > 0 3404 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3405endif 3406 3407############### 3408# Subprojects # 3409############### 3410 3411libvfio_user_dep = not_found 3412if have_system and vfio_user_server_allowed 3413 libvfio_user_proj = subproject('libvfio-user', required: true) 3414 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3415endif 3416 3417vhost_user = not_found 3418if host_os == 'linux' and have_vhost_user 3419 libvhost_user = subproject('libvhost-user') 3420 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3421endif 3422 3423libvduse = not_found 3424if have_libvduse 3425 libvduse_proj = subproject('libvduse') 3426 libvduse = libvduse_proj.get_variable('libvduse_dep') 3427endif 3428 3429##################### 3430# Generated sources # 3431##################### 3432 3433config_host_h = configure_file(output: 'config-host.h', configuration: config_host_data) 3434genh += config_host_h 3435 3436hxtool = find_program('scripts/hxtool') 3437shaderinclude = find_program('scripts/shaderinclude.py') 3438qapi_gen = find_program('scripts/qapi-gen.py') 3439qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3440 meson.current_source_dir() / 'scripts/qapi/commands.py', 3441 meson.current_source_dir() / 'scripts/qapi/common.py', 3442 meson.current_source_dir() / 'scripts/qapi/error.py', 3443 meson.current_source_dir() / 'scripts/qapi/events.py', 3444 meson.current_source_dir() / 'scripts/qapi/expr.py', 3445 meson.current_source_dir() / 'scripts/qapi/gen.py', 3446 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3447 meson.current_source_dir() / 'scripts/qapi/main.py', 3448 meson.current_source_dir() / 'scripts/qapi/parser.py', 3449 meson.current_source_dir() / 'scripts/qapi/schema.py', 3450 meson.current_source_dir() / 'scripts/qapi/source.py', 3451 meson.current_source_dir() / 'scripts/qapi/types.py', 3452 meson.current_source_dir() / 'scripts/qapi/features.py', 3453 meson.current_source_dir() / 'scripts/qapi/visit.py', 3454 meson.current_source_dir() / 'scripts/qapi-gen.py' 3455] 3456 3457tracetool = [ 3458 python, files('scripts/tracetool.py'), 3459 '--backend=' + ','.join(get_option('trace_backends')) 3460] 3461tracetool_depends = files( 3462 'scripts/tracetool/backend/log.py', 3463 'scripts/tracetool/backend/__init__.py', 3464 'scripts/tracetool/backend/dtrace.py', 3465 'scripts/tracetool/backend/ftrace.py', 3466 'scripts/tracetool/backend/simple.py', 3467 'scripts/tracetool/backend/syslog.py', 3468 'scripts/tracetool/backend/ust.py', 3469 'scripts/tracetool/format/ust_events_c.py', 3470 'scripts/tracetool/format/ust_events_h.py', 3471 'scripts/tracetool/format/__init__.py', 3472 'scripts/tracetool/format/d.py', 3473 'scripts/tracetool/format/simpletrace_stap.py', 3474 'scripts/tracetool/format/c.py', 3475 'scripts/tracetool/format/h.py', 3476 'scripts/tracetool/format/log_stap.py', 3477 'scripts/tracetool/format/stap.py', 3478 'scripts/tracetool/__init__.py', 3479) 3480 3481qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3482 meson.current_source_dir(), 3483 get_option('pkgversion'), meson.project_version()] 3484qemu_version = custom_target('qemu-version.h', 3485 output: 'qemu-version.h', 3486 command: qemu_version_cmd, 3487 capture: true, 3488 build_by_default: true, 3489 build_always_stale: true) 3490genh += qemu_version 3491 3492hxdep = [] 3493hx_headers = [ 3494 ['qemu-options.hx', 'qemu-options.def'], 3495 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3496] 3497if have_system 3498 hx_headers += [ 3499 ['hmp-commands.hx', 'hmp-commands.h'], 3500 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3501 ] 3502endif 3503foreach d : hx_headers 3504 hxdep += custom_target(d[1], 3505 input: files(d[0]), 3506 output: d[1], 3507 capture: true, 3508 command: [hxtool, '-h', '@INPUT0@']) 3509endforeach 3510genh += hxdep 3511 3512############### 3513# Trace files # 3514############### 3515 3516# TODO: add each directory to the subdirs from its own meson.build, once 3517# we have those 3518trace_events_subdirs = [ 3519 'crypto', 3520 'qapi', 3521 'qom', 3522 'monitor', 3523 'util', 3524 'gdbstub', 3525] 3526if have_linux_user 3527 trace_events_subdirs += [ 'linux-user' ] 3528endif 3529if have_bsd_user 3530 trace_events_subdirs += [ 'bsd-user' ] 3531endif 3532if have_block 3533 trace_events_subdirs += [ 3534 'authz', 3535 'block', 3536 'chardev', 3537 'io', 3538 'nbd', 3539 'scsi', 3540 ] 3541endif 3542if have_system 3543 trace_events_subdirs += [ 3544 'accel/kvm', 3545 'audio', 3546 'backends', 3547 'backends/tpm', 3548 'ebpf', 3549 'hw/9pfs', 3550 'hw/acpi', 3551 'hw/adc', 3552 'hw/alpha', 3553 'hw/arm', 3554 'hw/audio', 3555 'hw/block', 3556 'hw/char', 3557 'hw/display', 3558 'hw/dma', 3559 'hw/fsi', 3560 'hw/hyperv', 3561 'hw/i2c', 3562 'hw/i386', 3563 'hw/i386/xen', 3564 'hw/i386/kvm', 3565 'hw/ide', 3566 'hw/input', 3567 'hw/intc', 3568 'hw/isa', 3569 'hw/mem', 3570 'hw/mips', 3571 'hw/misc', 3572 'hw/misc/macio', 3573 'hw/net', 3574 'hw/net/can', 3575 'hw/nubus', 3576 'hw/nvme', 3577 'hw/nvram', 3578 'hw/pci', 3579 'hw/pci-host', 3580 'hw/ppc', 3581 'hw/rtc', 3582 'hw/riscv', 3583 'hw/s390x', 3584 'hw/scsi', 3585 'hw/sd', 3586 'hw/sensor', 3587 'hw/sh4', 3588 'hw/sparc', 3589 'hw/sparc64', 3590 'hw/ssi', 3591 'hw/timer', 3592 'hw/tpm', 3593 'hw/ufs', 3594 'hw/usb', 3595 'hw/vfio', 3596 'hw/virtio', 3597 'hw/watchdog', 3598 'hw/xen', 3599 'hw/gpio', 3600 'migration', 3601 'net', 3602 'system', 3603 'ui', 3604 'hw/remote', 3605 ] 3606endif 3607if have_system or have_user 3608 trace_events_subdirs += [ 3609 'accel/tcg', 3610 'hw/core', 3611 'target/arm', 3612 'target/arm/hvf', 3613 'target/hppa', 3614 'target/i386', 3615 'target/i386/kvm', 3616 'target/loongarch', 3617 'target/mips/tcg', 3618 'target/ppc', 3619 'target/riscv', 3620 'target/s390x', 3621 'target/s390x/kvm', 3622 'target/sparc', 3623 ] 3624endif 3625 3626################### 3627# Collect sources # 3628################### 3629 3630authz_ss = ss.source_set() 3631blockdev_ss = ss.source_set() 3632block_ss = ss.source_set() 3633chardev_ss = ss.source_set() 3634common_ss = ss.source_set() 3635crypto_ss = ss.source_set() 3636hwcore_ss = ss.source_set() 3637io_ss = ss.source_set() 3638qmp_ss = ss.source_set() 3639qom_ss = ss.source_set() 3640system_ss = ss.source_set() 3641specific_fuzz_ss = ss.source_set() 3642specific_ss = ss.source_set() 3643rust_devices_ss = ss.source_set() 3644stub_ss = ss.source_set() 3645trace_ss = ss.source_set() 3646user_ss = ss.source_set() 3647util_ss = ss.source_set() 3648 3649# accel modules 3650qtest_module_ss = ss.source_set() 3651 3652modules = {} 3653target_modules = {} 3654hw_arch = {} 3655target_arch = {} 3656target_system_arch = {} 3657target_user_arch = {} 3658 3659# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3660# that is filled in by qapi/. 3661subdir('qapi') 3662subdir('qobject') 3663subdir('stubs') 3664subdir('trace') 3665subdir('util') 3666subdir('qom') 3667subdir('authz') 3668subdir('crypto') 3669subdir('ui') 3670subdir('gdbstub') 3671if have_system 3672 subdir('hw') 3673else 3674 subdir('hw/core') 3675endif 3676 3677if enable_modules 3678 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3679 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3680endif 3681 3682qom_ss = qom_ss.apply({}) 3683libqom = static_library('qom', qom_ss.sources() + genh, 3684 dependencies: [qom_ss.dependencies()], 3685 build_by_default: false) 3686qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3687 dependencies: qom_ss.dependencies()) 3688 3689event_loop_base = files('event-loop-base.c') 3690event_loop_base = static_library('event-loop-base', 3691 sources: event_loop_base + genh, 3692 build_by_default: false) 3693event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3694 dependencies: [qom]) 3695 3696stub_ss = stub_ss.apply({}) 3697 3698util_ss.add_all(trace_ss) 3699util_ss = util_ss.apply({}) 3700libqemuutil = static_library('qemuutil', 3701 build_by_default: false, 3702 sources: util_ss.sources() + stub_ss.sources() + genh, 3703 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3704qemuutil_deps = [event_loop_base] 3705if host_os != 'windows' 3706 qemuutil_deps += [rt] 3707endif 3708qemuutil = declare_dependency(link_with: libqemuutil, 3709 sources: genh + version_res, 3710 dependencies: qemuutil_deps) 3711 3712if have_system or have_user 3713 decodetree = generator(find_program('scripts/decodetree.py'), 3714 output: 'decode-@BASENAME@.c.inc', 3715 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3716 subdir('libdecnumber') 3717 subdir('target') 3718endif 3719 3720subdir('audio') 3721subdir('io') 3722subdir('chardev') 3723subdir('fsdev') 3724subdir('dump') 3725 3726if have_block 3727 block_ss.add(files( 3728 'block.c', 3729 'blockjob.c', 3730 'job.c', 3731 'qemu-io-cmds.c', 3732 )) 3733 if config_host_data.get('CONFIG_REPLICATION') 3734 block_ss.add(files('replication.c')) 3735 endif 3736 3737 subdir('nbd') 3738 subdir('scsi') 3739 subdir('block') 3740 3741 blockdev_ss.add(files( 3742 'blockdev.c', 3743 'blockdev-nbd.c', 3744 'iothread.c', 3745 'job-qmp.c', 3746 )) 3747 3748 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3749 # os-win32.c does not 3750 if host_os == 'windows' 3751 system_ss.add(files('os-win32.c')) 3752 else 3753 blockdev_ss.add(files('os-posix.c')) 3754 endif 3755endif 3756 3757common_ss.add(files('cpu-common.c')) 3758specific_ss.add(files('cpu-target.c')) 3759 3760subdir('system') 3761 3762# Work around a gcc bug/misfeature wherein constant propagation looks 3763# through an alias: 3764# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3765# to guess that a const variable is always zero. Without lto, this is 3766# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3767# without lto, not even the alias is required -- we simply use different 3768# declarations in different compilation units. 3769pagevary = files('page-vary-common.c') 3770if get_option('b_lto') 3771 pagevary_flags = ['-fno-lto'] 3772 if get_option('cfi') 3773 pagevary_flags += '-fno-sanitize=cfi-icall' 3774 endif 3775 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3776 c_args: pagevary_flags) 3777 pagevary = declare_dependency(link_with: pagevary) 3778endif 3779common_ss.add(pagevary) 3780specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3781 3782subdir('backends') 3783subdir('disas') 3784subdir('migration') 3785subdir('monitor') 3786subdir('net') 3787subdir('replay') 3788subdir('semihosting') 3789subdir('stats') 3790subdir('tcg') 3791subdir('fpu') 3792subdir('accel') 3793subdir('plugins') 3794subdir('ebpf') 3795 3796if 'CONFIG_TCG' in config_all_accel 3797 subdir('contrib/plugins') 3798endif 3799 3800common_user_inc = [] 3801 3802subdir('common-user') 3803subdir('bsd-user') 3804subdir('linux-user') 3805 3806# needed for fuzzing binaries 3807subdir('tests/qtest/libqos') 3808subdir('tests/qtest/fuzz') 3809 3810# accel modules 3811target_modules += { 'accel' : { 'qtest': qtest_module_ss }} 3812 3813############################################## 3814# Internal static_libraries and dependencies # 3815############################################## 3816 3817modinfo_collect = find_program('scripts/modinfo-collect.py') 3818modinfo_generate = find_program('scripts/modinfo-generate.py') 3819modinfo_files = [] 3820 3821block_mods = [] 3822system_mods = [] 3823emulator_modules = [] 3824foreach d, list : modules 3825 if not (d == 'block' ? have_block : have_system) 3826 continue 3827 endif 3828 3829 foreach m, module_ss : list 3830 if enable_modules 3831 module_ss.add(modulecommon) 3832 module_ss = module_ss.apply(config_all_devices, strict: false) 3833 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3834 dependencies: module_ss.dependencies(), pic: true) 3835 if d == 'block' 3836 block_mods += sl 3837 else 3838 system_mods += sl 3839 endif 3840 emulator_modules += shared_module(sl.name(), 3841 name_prefix: '', 3842 objects: sl.extract_all_objects(recursive: false), 3843 dependencies: module_ss.dependencies(), 3844 install: true, 3845 install_dir: qemu_moddir) 3846 if module_ss.sources() != [] 3847 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3848 # input. Sources can be used multiple times but objects are 3849 # unique when it comes to lookup in compile_commands.json. 3850 # Depnds on a mesion version with 3851 # https://github.com/mesonbuild/meson/pull/8900 3852 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3853 output: d + '-' + m + '.modinfo', 3854 input: module_ss.sources() + genh, 3855 capture: true, 3856 command: [modinfo_collect, module_ss.sources()]) 3857 endif 3858 else 3859 if d == 'block' 3860 block_ss.add_all(module_ss) 3861 else 3862 system_ss.add_all(module_ss) 3863 endif 3864 endif 3865 endforeach 3866endforeach 3867 3868foreach d, list : target_modules 3869 foreach m, module_ss : list 3870 if enable_modules 3871 module_ss.add(modulecommon) 3872 foreach target : target_dirs 3873 if target.endswith('-softmmu') 3874 config_target = config_target_mak[target] 3875 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3876 c_args = ['-DCOMPILING_PER_TARGET', 3877 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3878 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3879 target_module_ss = module_ss.apply(config_target, strict: false) 3880 if target_module_ss.sources() != [] 3881 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3882 sl = static_library(module_name, 3883 [genh, target_module_ss.sources()], 3884 dependencies: target_module_ss.dependencies(), 3885 include_directories: target_inc, 3886 c_args: c_args, 3887 pic: true) 3888 system_mods += sl 3889 emulator_modules += shared_module(sl.name(), 3890 name_prefix: '', 3891 objects: sl.extract_all_objects(recursive: false), 3892 dependencies: target_module_ss.dependencies(), 3893 install: true, 3894 install_dir: qemu_moddir) 3895 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3896 modinfo_files += custom_target(module_name + '.modinfo', 3897 output: module_name + '.modinfo', 3898 input: target_module_ss.sources() + genh, 3899 capture: true, 3900 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3901 endif 3902 endif 3903 endforeach 3904 else 3905 specific_ss.add_all(module_ss) 3906 endif 3907 endforeach 3908endforeach 3909 3910if enable_modules 3911 foreach target : target_dirs 3912 if target.endswith('-softmmu') 3913 config_target = config_target_mak[target] 3914 config_devices_mak = target + '-config-devices.mak' 3915 modinfo_src = custom_target('modinfo-' + target + '.c', 3916 output: 'modinfo-' + target + '.c', 3917 input: modinfo_files, 3918 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3919 capture: true) 3920 3921 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3922 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3923 3924 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3925 hw_arch[arch].add(modinfo_dep) 3926 endif 3927 endforeach 3928 3929 if emulator_modules.length() > 0 3930 alias_target('modules', emulator_modules) 3931 endif 3932endif 3933 3934nm = find_program('nm') 3935undefsym = find_program('scripts/undefsym.py') 3936block_syms = custom_target('block.syms', output: 'block.syms', 3937 input: [libqemuutil, block_mods], 3938 capture: true, 3939 command: [undefsym, nm, '@INPUT@']) 3940qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3941 input: [libqemuutil, system_mods], 3942 capture: true, 3943 command: [undefsym, nm, '@INPUT@']) 3944 3945authz_ss = authz_ss.apply({}) 3946libauthz = static_library('authz', authz_ss.sources() + genh, 3947 dependencies: [authz_ss.dependencies()], 3948 build_by_default: false) 3949 3950authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3951 dependencies: [authz_ss.dependencies(), qom]) 3952 3953crypto_ss = crypto_ss.apply({}) 3954libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3955 dependencies: [crypto_ss.dependencies()], 3956 build_by_default: false) 3957 3958crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3959 dependencies: [crypto_ss.dependencies(), authz, qom]) 3960 3961io_ss = io_ss.apply({}) 3962libio = static_library('io', io_ss.sources() + genh, 3963 dependencies: [io_ss.dependencies()], 3964 link_with: libqemuutil, 3965 build_by_default: false) 3966 3967io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3968 dependencies: [io_ss.dependencies(), crypto, qom]) 3969 3970libmigration = static_library('migration', sources: migration_files + genh, 3971 build_by_default: false) 3972migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3973 dependencies: [qom, io]) 3974system_ss.add(migration) 3975 3976block_ss = block_ss.apply({}) 3977libblock = static_library('block', block_ss.sources() + genh, 3978 dependencies: block_ss.dependencies(), 3979 build_by_default: false) 3980 3981block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3982 dependencies: [block_ss.dependencies(), crypto, io]) 3983 3984blockdev_ss = blockdev_ss.apply({}) 3985libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3986 dependencies: blockdev_ss.dependencies(), 3987 build_by_default: false) 3988 3989blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3990 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3991 3992qmp_ss = qmp_ss.apply({}) 3993libqmp = static_library('qmp', qmp_ss.sources() + genh, 3994 dependencies: qmp_ss.dependencies(), 3995 build_by_default: false) 3996 3997qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3998 dependencies: qmp_ss.dependencies()) 3999 4000libchardev = static_library('chardev', chardev_ss.sources() + genh, 4001 dependencies: chardev_ss.dependencies(), 4002 build_by_default: false) 4003 4004chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 4005 dependencies: chardev_ss.dependencies()) 4006 4007hwcore_ss = hwcore_ss.apply({}) 4008libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 4009 build_by_default: false) 4010hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 4011common_ss.add(hwcore) 4012 4013########### 4014# Targets # 4015########### 4016 4017system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 4018common_ss.add(qom, qemuutil) 4019 4020common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 4021common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 4022 4023# Note that this library is never used directly (only through extract_objects) 4024# and is not built by default; therefore, source files not used by the build 4025# configuration will be in build.ninja, but are never built by default. 4026common_all = static_library('common', 4027 build_by_default: false, 4028 sources: common_ss.all_sources() + genh, 4029 include_directories: common_user_inc, 4030 implicit_include_directories: false, 4031 dependencies: common_ss.all_dependencies()) 4032 4033if have_rust 4034 # We would like to use --generate-cstr, but it is only available 4035 # starting with bindgen 0.66.0. The oldest supported versions 4036 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file. 4037 bindgen_args = [ 4038 '--disable-header-comment', 4039 '--raw-line', '// @generated', 4040 '--ctypes-prefix', 'std::os::raw', 4041 '--generate-block', 4042 '--impl-debug', 4043 '--no-doc-comments', 4044 '--with-derive-default', 4045 '--no-layout-tests', 4046 '--no-prepend-enum-name', 4047 '--allowlist-file', meson.project_source_root() + '/include/.*', 4048 '--allowlist-file', meson.project_source_root() + '/.*', 4049 '--allowlist-file', meson.project_build_root() + '/.*' 4050 ] 4051 if not rustfmt.found() 4052 if bindgen.version().version_compare('<0.65.0') 4053 bindgen_args += ['--no-rustfmt-bindings'] 4054 else 4055 bindgen_args += ['--formatter', 'none'] 4056 endif 4057 endif 4058 if bindgen.version().version_compare('>=0.66.0') 4059 bindgen_args += ['--rust-target', '1.59'] 4060 endif 4061 if bindgen.version().version_compare('<0.61.0') 4062 # default in 0.61+ 4063 bindgen_args += ['--size_t-is-usize'] 4064 else 4065 bindgen_args += ['--merge-extern-blocks'] 4066 endif 4067 c_enums = [ 4068 'DeviceCategory', 4069 'GpioPolarity', 4070 'MachineInitPhase', 4071 'MemoryDeviceInfoKind', 4072 'MigrationPolicy', 4073 'MigrationPriority', 4074 'QEMUChrEvent', 4075 'QEMUClockType', 4076 'ResetType', 4077 'device_endian', 4078 'module_init_type', 4079 ] 4080 foreach enum : c_enums 4081 bindgen_args += ['--rustified-enum', enum] 4082 endforeach 4083 c_bitfields = [ 4084 'ClockEvent', 4085 'VMStateFlags', 4086 ] 4087 foreach enum : c_bitfields 4088 bindgen_args += ['--bitfield-enum', enum] 4089 endforeach 4090 c_nocopy = [ 4091 'QEMUTimer', 4092 ] 4093 # Used to customize Drop trait 4094 foreach struct : c_nocopy 4095 bindgen_args += ['--no-copy', struct] 4096 endforeach 4097 4098 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 4099 # 4100 # Rust bindings generation with `bindgen` might fail in some cases where the 4101 # detected `libclang` does not match the expected `clang` version/target. In 4102 # this case you must pass the path to `clang` and `libclang` to your build 4103 # command invocation using the environment variables CLANG_PATH and 4104 # LIBCLANG_PATH 4105 bindings_rs = rust.bindgen( 4106 input: 'rust/wrapper.h', 4107 dependencies: common_ss.all_dependencies(), 4108 output: 'bindings.inc.rs', 4109 include_directories: include_directories('.', 'include'), 4110 bindgen_version: ['>=0.60.0'], 4111 args: bindgen_args, 4112 ) 4113 subdir('rust') 4114endif 4115 4116 4117feature_to_c = find_program('scripts/feature_to_c.py') 4118rust_root_crate = find_program('scripts/rust/rust_root_crate.sh') 4119 4120if host_os == 'darwin' 4121 entitlement = find_program('scripts/entitlement.sh') 4122endif 4123 4124traceable = [] 4125emulators = {} 4126foreach target : target_dirs 4127 config_target = config_target_mak[target] 4128 target_name = config_target['TARGET_NAME'] 4129 target_base_arch = config_target['TARGET_BASE_ARCH'] 4130 arch_srcs = [config_target_h[target]] 4131 arch_deps = [] 4132 c_args = ['-DCOMPILING_PER_TARGET', 4133 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4134 ] 4135 link_args = emulator_link_args 4136 4137 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4138 if host_os == 'linux' 4139 target_inc += include_directories('linux-headers', is_system: true) 4140 endif 4141 if target.endswith('-softmmu') 4142 target_type='system' 4143 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4144 arch_srcs += t.sources() 4145 arch_deps += t.dependencies() 4146 4147 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4148 if hw_arch.has_key(hw_dir) 4149 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4150 arch_srcs += hw.sources() 4151 arch_deps += hw.dependencies() 4152 endif 4153 4154 c_args += ['-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4155 arch_srcs += config_devices_h[target] 4156 link_args += ['@block.syms', '@qemu.syms'] 4157 else 4158 abi = config_target['TARGET_ABI_DIR'] 4159 target_type='user' 4160 target_inc += common_user_inc 4161 if target_base_arch in target_user_arch 4162 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4163 arch_srcs += t.sources() 4164 arch_deps += t.dependencies() 4165 endif 4166 if 'CONFIG_LINUX_USER' in config_target 4167 base_dir = 'linux-user' 4168 endif 4169 if 'CONFIG_BSD_USER' in config_target 4170 base_dir = 'bsd-user' 4171 target_inc += include_directories('bsd-user/' / host_os) 4172 target_inc += include_directories('bsd-user/host/' / host_arch) 4173 dir = base_dir / abi 4174 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4175 endif 4176 target_inc += include_directories( 4177 base_dir, 4178 base_dir / abi, 4179 ) 4180 if 'CONFIG_LINUX_USER' in config_target 4181 dir = base_dir / abi 4182 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4183 if config_target.has_key('TARGET_SYSTBL_ABI') 4184 arch_srcs += \ 4185 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4186 extra_args : config_target['TARGET_SYSTBL_ABI']) 4187 endif 4188 endif 4189 endif 4190 4191 if 'TARGET_XML_FILES' in config_target 4192 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4193 output: target + '-gdbstub-xml.c', 4194 input: files(config_target['TARGET_XML_FILES'].split()), 4195 command: [feature_to_c, '@INPUT@'], 4196 capture: true) 4197 arch_srcs += gdbstub_xml 4198 endif 4199 4200 t = target_arch[target_base_arch].apply(config_target, strict: false) 4201 arch_srcs += t.sources() 4202 arch_deps += t.dependencies() 4203 4204 target_common = common_ss.apply(config_target, strict: false) 4205 objects = common_all.extract_objects(target_common.sources()) 4206 arch_deps += target_common.dependencies() 4207 4208 target_specific = specific_ss.apply(config_target, strict: false) 4209 arch_srcs += target_specific.sources() 4210 arch_deps += target_specific.dependencies() 4211 4212 if have_rust and target_type == 'system' 4213 target_rust = rust_devices_ss.apply(config_target, strict: false) 4214 crates = [] 4215 foreach dep : target_rust.dependencies() 4216 crates += dep.get_variable('crate') 4217 endforeach 4218 if crates.length() > 0 4219 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4220 output: 'rust_' + target.underscorify() + '.rs', 4221 command: [rust_root_crate, crates], 4222 capture: true, 4223 build_by_default: true, 4224 build_always_stale: true) 4225 rlib = static_library('rust_' + target.underscorify(), 4226 rlib_rs, 4227 dependencies: target_rust.dependencies(), 4228 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4229 rust_abi: 'c') 4230 arch_deps += declare_dependency(link_whole: [rlib]) 4231 endif 4232 endif 4233 4234 # allow using headers from the dependencies but do not include the sources, 4235 # because this emulator only needs those in "objects". For external 4236 # dependencies, the full dependency is included below in the executable. 4237 lib_deps = [] 4238 foreach dep : arch_deps 4239 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4240 endforeach 4241 4242 lib = static_library('qemu-' + target, 4243 sources: arch_srcs + genh, 4244 dependencies: lib_deps, 4245 objects: objects, 4246 include_directories: target_inc, 4247 c_args: c_args, 4248 build_by_default: false) 4249 4250 if target.endswith('-softmmu') 4251 execs = [{ 4252 'name': 'qemu-system-' + target_name, 4253 'win_subsystem': 'console', 4254 'sources': files('system/main.c'), 4255 'dependencies': [sdl] 4256 }] 4257 if host_os == 'windows' and (sdl.found() or gtk.found()) 4258 execs += [{ 4259 'name': 'qemu-system-' + target_name + 'w', 4260 'win_subsystem': 'windows', 4261 'sources': files('system/main.c'), 4262 'dependencies': [sdl] 4263 }] 4264 endif 4265 if get_option('fuzzing') 4266 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4267 execs += [{ 4268 'name': 'qemu-fuzz-' + target_name, 4269 'win_subsystem': 'console', 4270 'sources': specific_fuzz.sources(), 4271 'dependencies': specific_fuzz.dependencies(), 4272 }] 4273 endif 4274 else 4275 execs = [{ 4276 'name': 'qemu-' + target_name, 4277 'win_subsystem': 'console', 4278 'sources': [], 4279 'dependencies': [] 4280 }] 4281 endif 4282 foreach exe: execs 4283 exe_name = exe['name'] 4284 if host_os == 'darwin' 4285 exe_name += '-unsigned' 4286 endif 4287 4288 emulator = executable(exe_name, exe['sources'], 4289 install: true, 4290 c_args: c_args, 4291 dependencies: arch_deps + exe['dependencies'], 4292 objects: lib.extract_all_objects(recursive: true), 4293 link_depends: [block_syms, qemu_syms], 4294 link_args: link_args, 4295 win_subsystem: exe['win_subsystem']) 4296 4297 if host_os == 'darwin' 4298 icon = 'pc-bios/qemu.rsrc' 4299 build_input = [emulator, files(icon)] 4300 install_input = [ 4301 get_option('bindir') / exe_name, 4302 meson.current_source_dir() / icon 4303 ] 4304 if 'CONFIG_HVF' in config_target 4305 entitlements = 'accel/hvf/entitlements.plist' 4306 build_input += files(entitlements) 4307 install_input += meson.current_source_dir() / entitlements 4308 endif 4309 4310 emulators += {exe['name'] : custom_target(exe['name'], 4311 input: build_input, 4312 output: exe['name'], 4313 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4314 } 4315 4316 meson.add_install_script(entitlement, '--install', 4317 get_option('bindir') / exe['name'], 4318 install_input) 4319 else 4320 emulators += {exe['name']: emulator} 4321 endif 4322 4323 traceable += [{ 4324 'exe': exe['name'], 4325 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4326 }] 4327 4328 endforeach 4329endforeach 4330 4331# Other build targets 4332 4333if get_option('plugins') 4334 install_headers('include/qemu/qemu-plugin.h') 4335 if host_os == 'windows' 4336 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4337 # so that plugin authors can compile against it. 4338 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4339 endif 4340endif 4341 4342subdir('qga') 4343 4344# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4345# when we don't build tools or system 4346if xkbcommon.found() 4347 # used for the update-keymaps target, so include rules even if !have_tools 4348 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4349 dependencies: [qemuutil, xkbcommon], install: have_tools) 4350endif 4351 4352if have_tools 4353 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4354 link_args: '@block.syms', link_depends: block_syms, 4355 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4356 qemu_io = executable('qemu-io', files('qemu-io.c'), 4357 link_args: '@block.syms', link_depends: block_syms, 4358 dependencies: [block, qemuutil], install: true) 4359 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4360 link_args: '@block.syms', link_depends: block_syms, 4361 dependencies: [blockdev, qemuutil, selinux], 4362 install: true) 4363 4364 subdir('storage-daemon') 4365 4366 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4367 traceable += [{ 4368 'exe': exe, 4369 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4370 }] 4371 endforeach 4372 4373 subdir('contrib/elf2dmp') 4374 4375 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4376 dependencies: [qemuutil, rt], 4377 install: true) 4378 4379 if have_vhost_user 4380 subdir('contrib/vhost-user-blk') 4381 subdir('contrib/vhost-user-gpu') 4382 subdir('contrib/vhost-user-input') 4383 subdir('contrib/vhost-user-scsi') 4384 endif 4385 4386 if host_os == 'linux' 4387 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4388 dependencies: [qemuutil, libcap_ng], 4389 install: true, 4390 install_dir: get_option('libexecdir')) 4391 4392 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4393 dependencies: [authz, crypto, io, qom, qemuutil, 4394 libcap_ng, mpathpersist], 4395 install: true) 4396 4397 if cpu in ['x86', 'x86_64'] 4398 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4399 dependencies: [authz, crypto, io, qom, qemuutil, 4400 libcap_ng, mpathpersist], 4401 install: true) 4402 endif 4403 endif 4404 4405 if have_ivshmem 4406 subdir('contrib/ivshmem-client') 4407 subdir('contrib/ivshmem-server') 4408 endif 4409endif 4410 4411if stap.found() 4412 foreach t: traceable 4413 foreach stp: [ 4414 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4415 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4416 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4417 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4418 ] 4419 cmd = [ 4420 tracetool, '--group=all', '--format=' + stp['fmt'], 4421 '--binary=' + stp['bin'], 4422 '--probe-prefix=' + t['probe-prefix'], 4423 '@INPUT@', '@OUTPUT@' 4424 ] 4425 4426 custom_target(t['exe'] + stp['ext'], 4427 input: trace_events_all, 4428 output: t['exe'] + stp['ext'], 4429 install: stp['install'], 4430 install_dir: get_option('datadir') / 'systemtap/tapset', 4431 command: cmd, 4432 depend_files: tracetool_depends) 4433 endforeach 4434 endforeach 4435endif 4436 4437subdir('scripts') 4438subdir('tools') 4439subdir('pc-bios') 4440subdir('docs') 4441subdir('tests') 4442if gtk.found() 4443 subdir('po') 4444endif 4445 4446if host_machine.system() == 'windows' 4447 nsis_cmd = [ 4448 find_program('scripts/nsis.py'), 4449 '@OUTPUT@', 4450 get_option('prefix'), 4451 meson.current_source_dir(), 4452 glib_pc.get_variable('bindir'), 4453 host_machine.cpu(), 4454 '--', 4455 '-DDISPLAYVERSION=' + meson.project_version(), 4456 ] 4457 if build_docs 4458 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4459 endif 4460 if gtk.found() 4461 nsis_cmd += '-DCONFIG_GTK=y' 4462 endif 4463 4464 nsis = custom_target('nsis', 4465 output: 'qemu-setup-' + meson.project_version() + '.exe', 4466 input: files('qemu.nsi'), 4467 build_always_stale: true, 4468 command: nsis_cmd + ['@INPUT@']) 4469 alias_target('installer', nsis) 4470endif 4471 4472######################### 4473# Configuration summary # 4474######################### 4475 4476# Build environment 4477summary_info = {} 4478summary_info += {'Build directory': meson.current_build_dir()} 4479summary_info += {'Source path': meson.current_source_dir()} 4480summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4481summary(summary_info, bool_yn: true, section: 'Build environment') 4482 4483# Directories 4484summary_info += {'Install prefix': get_option('prefix')} 4485summary_info += {'BIOS directory': qemu_datadir} 4486pathsep = host_os == 'windows' ? ';' : ':' 4487summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4488summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4489summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4490summary_info += {'module directory': qemu_moddir} 4491summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4492summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4493summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4494if host_os != 'windows' 4495 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4496 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4497else 4498 summary_info += {'local state directory': 'queried at runtime'} 4499endif 4500summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4501summary(summary_info, bool_yn: true, section: 'Directories') 4502 4503# Host binaries 4504summary_info = {} 4505summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4506summary_info += {'sphinx-build': sphinx_build} 4507 4508# FIXME: the [binaries] section of machine files, which can be probed 4509# with find_program(), would be great for passing gdb and genisoimage 4510# paths from configure to Meson. However, there seems to be no way to 4511# hide a program (for example if gdb is too old). 4512if config_host.has_key('GDB') 4513 summary_info += {'gdb': config_host['GDB']} 4514endif 4515summary_info += {'iasl': iasl} 4516summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4517if host_os == 'windows' and have_ga 4518 summary_info += {'wixl': wixl} 4519endif 4520if slirp.found() and have_system 4521 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4522endif 4523summary(summary_info, bool_yn: true, section: 'Host binaries') 4524 4525# Configurable features 4526summary_info = {} 4527summary_info += {'Documentation': build_docs} 4528summary_info += {'system-mode emulation': have_system} 4529summary_info += {'user-mode emulation': have_user} 4530summary_info += {'block layer': have_block} 4531summary_info += {'Install blobs': get_option('install_blobs')} 4532summary_info += {'module support': enable_modules} 4533if enable_modules 4534 summary_info += {'alternative module path': get_option('module_upgrades')} 4535endif 4536summary_info += {'fuzzing support': get_option('fuzzing')} 4537if have_system 4538 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4539endif 4540summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4541if 'simple' in get_option('trace_backends') 4542 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4543endif 4544summary_info += {'D-Bus display': dbus_display} 4545summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4546summary_info += {'Relocatable install': get_option('relocatable')} 4547summary_info += {'vhost-kernel support': have_vhost_kernel} 4548summary_info += {'vhost-net support': have_vhost_net} 4549summary_info += {'vhost-user support': have_vhost_user} 4550summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4551summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4552summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4553summary_info += {'build guest agent': have_ga} 4554summary(summary_info, bool_yn: true, section: 'Configurable features') 4555 4556# Compilation information 4557summary_info = {} 4558summary_info += {'host CPU': cpu} 4559summary_info += {'host endianness': build_machine.endian()} 4560summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4561summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4562if 'cpp' in all_languages 4563 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4564else 4565 summary_info += {'C++ compiler': false} 4566endif 4567if 'objc' in all_languages 4568 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4569else 4570 summary_info += {'Objective-C compiler': false} 4571endif 4572summary_info += {'Rust support': have_rust} 4573if have_rust 4574 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4575 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4576 summary_info += {'rustc version': rustc.version()} 4577 summary_info += {'bindgen': bindgen.full_path()} 4578 summary_info += {'bindgen version': bindgen.version()} 4579endif 4580option_cflags = (get_option('debug') ? ['-g'] : []) 4581if get_option('optimization') != 'plain' 4582 option_cflags += ['-O' + get_option('optimization')] 4583endif 4584summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4585if 'cpp' in all_languages 4586 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4587endif 4588if 'objc' in all_languages 4589 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4590endif 4591link_args = get_option('c_link_args') 4592if link_args.length() > 0 4593 summary_info += {'LDFLAGS': ' '.join(link_args)} 4594endif 4595summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4596if 'cpp' in all_languages 4597 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4598endif 4599if 'objc' in all_languages 4600 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4601endif 4602summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4603summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4604summary_info += {'PIE': get_option('b_pie')} 4605summary_info += {'static build': get_option('prefer_static')} 4606summary_info += {'malloc trim support': has_malloc_trim} 4607summary_info += {'membarrier': have_membarrier} 4608summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4609summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4610summary_info += {'mutex debugging': get_option('debug_mutex')} 4611summary_info += {'memory allocator': get_option('malloc')} 4612summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4613summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4614summary_info += {'gcov': get_option('b_coverage')} 4615summary_info += {'thread sanitizer': get_option('tsan')} 4616summary_info += {'CFI support': get_option('cfi')} 4617if get_option('cfi') 4618 summary_info += {'CFI debug support': get_option('cfi_debug')} 4619endif 4620summary_info += {'strip binaries': get_option('strip')} 4621summary_info += {'sparse': sparse} 4622summary_info += {'mingw32 support': host_os == 'windows'} 4623summary(summary_info, bool_yn: true, section: 'Compilation') 4624 4625# snarf the cross-compilation information for tests 4626summary_info = {} 4627have_cross = false 4628foreach target: target_dirs 4629 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4630 if fs.exists(tcg_mak) 4631 config_cross_tcg = keyval.load(tcg_mak) 4632 if 'CC' in config_cross_tcg 4633 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4634 have_cross = true 4635 endif 4636 endif 4637endforeach 4638if have_cross 4639 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4640endif 4641 4642# Targets and accelerators 4643summary_info = {} 4644if have_system 4645 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4646 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4647 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4648 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4649 summary_info += {'Xen support': xen.found()} 4650 if xen.found() 4651 summary_info += {'xen ctrl version': xen.version()} 4652 endif 4653 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4654endif 4655summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4656if config_all_accel.has_key('CONFIG_TCG') 4657 if get_option('tcg_interpreter') 4658 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4659 else 4660 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4661 endif 4662 summary_info += {'TCG plugins': get_option('plugins')} 4663 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4664 if have_linux_user or have_bsd_user 4665 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4666 endif 4667endif 4668summary_info += {'target list': ' '.join(target_dirs)} 4669if have_system 4670 summary_info += {'default devices': get_option('default_devices')} 4671 summary_info += {'out of process emulation': multiprocess_allowed} 4672 summary_info += {'vfio-user server': vfio_user_server_allowed} 4673endif 4674summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4675 4676# Block layer 4677summary_info = {} 4678summary_info += {'coroutine backend': coroutine_backend} 4679summary_info += {'coroutine pool': have_coroutine_pool} 4680if have_block 4681 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4682 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4683 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4684 summary_info += {'VirtFS (9P) support': have_virtfs} 4685 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4686 summary_info += {'bochs support': get_option('bochs').allowed()} 4687 summary_info += {'cloop support': get_option('cloop').allowed()} 4688 summary_info += {'dmg support': get_option('dmg').allowed()} 4689 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4690 summary_info += {'vdi support': get_option('vdi').allowed()} 4691 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4692 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4693 summary_info += {'vpc support': get_option('vpc').allowed()} 4694 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4695 summary_info += {'qed support': get_option('qed').allowed()} 4696 summary_info += {'parallels support': get_option('parallels').allowed()} 4697 summary_info += {'FUSE exports': fuse} 4698 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4699endif 4700summary(summary_info, bool_yn: true, section: 'Block layer support') 4701 4702# Crypto 4703summary_info = {} 4704summary_info += {'TLS priority': get_option('tls_priority')} 4705summary_info += {'GNUTLS support': gnutls} 4706if gnutls.found() 4707 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4708endif 4709summary_info += {'libgcrypt': gcrypt} 4710summary_info += {'nettle': nettle} 4711if nettle.found() 4712 summary_info += {' XTS': xts != 'private'} 4713endif 4714summary_info += {'SM4 ALG support': crypto_sm4} 4715summary_info += {'SM3 ALG support': crypto_sm3} 4716summary_info += {'AF_ALG support': have_afalg} 4717summary_info += {'rng-none': get_option('rng_none')} 4718summary_info += {'Linux keyring': have_keyring} 4719summary_info += {'Linux keyutils': keyutils} 4720summary(summary_info, bool_yn: true, section: 'Crypto') 4721 4722# UI 4723summary_info = {} 4724if host_os == 'darwin' 4725 summary_info += {'Cocoa support': cocoa} 4726endif 4727summary_info += {'SDL support': sdl} 4728summary_info += {'SDL image support': sdl_image} 4729summary_info += {'GTK support': gtk} 4730summary_info += {'pixman': pixman} 4731summary_info += {'VTE support': vte} 4732summary_info += {'PNG support': png} 4733summary_info += {'VNC support': vnc} 4734if vnc.found() 4735 summary_info += {'VNC SASL support': sasl} 4736 summary_info += {'VNC JPEG support': jpeg} 4737endif 4738summary_info += {'spice protocol support': spice_protocol} 4739if spice_protocol.found() 4740 summary_info += {' spice server support': spice} 4741endif 4742summary_info += {'curses support': curses} 4743summary_info += {'brlapi support': brlapi} 4744summary(summary_info, bool_yn: true, section: 'User interface') 4745 4746# Graphics backends 4747summary_info = {} 4748summary_info += {'VirGL support': virgl} 4749summary_info += {'Rutabaga support': rutabaga} 4750summary(summary_info, bool_yn: true, section: 'Graphics backends') 4751 4752# Audio backends 4753summary_info = {} 4754if host_os not in ['darwin', 'haiku', 'windows'] 4755 summary_info += {'OSS support': oss} 4756 summary_info += {'sndio support': sndio} 4757elif host_os == 'darwin' 4758 summary_info += {'CoreAudio support': coreaudio} 4759elif host_os == 'windows' 4760 summary_info += {'DirectSound support': dsound} 4761endif 4762if host_os == 'linux' 4763 summary_info += {'ALSA support': alsa} 4764 summary_info += {'PulseAudio support': pulse} 4765endif 4766summary_info += {'PipeWire support': pipewire} 4767summary_info += {'JACK support': jack} 4768summary(summary_info, bool_yn: true, section: 'Audio backends') 4769 4770# Network backends 4771summary_info = {} 4772if host_os == 'darwin' 4773 summary_info += {'vmnet.framework support': vmnet} 4774endif 4775summary_info += {'AF_XDP support': libxdp} 4776summary_info += {'slirp support': slirp} 4777summary_info += {'vde support': vde} 4778summary_info += {'netmap support': have_netmap} 4779summary_info += {'l2tpv3 support': have_l2tpv3} 4780summary(summary_info, bool_yn: true, section: 'Network backends') 4781 4782# Libraries 4783summary_info = {} 4784summary_info += {'libtasn1': tasn1} 4785summary_info += {'PAM': pam} 4786summary_info += {'iconv support': iconv} 4787summary_info += {'blkio support': blkio} 4788summary_info += {'curl support': curl} 4789summary_info += {'Multipath support': mpathpersist} 4790summary_info += {'Linux AIO support': libaio} 4791summary_info += {'Linux io_uring support': linux_io_uring} 4792summary_info += {'ATTR/XATTR support': libattr} 4793summary_info += {'RDMA support': rdma} 4794summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4795summary_info += {'libcap-ng support': libcap_ng} 4796summary_info += {'bpf support': libbpf} 4797summary_info += {'rbd support': rbd} 4798summary_info += {'smartcard support': cacard} 4799summary_info += {'U2F support': u2f} 4800summary_info += {'libusb': libusb} 4801summary_info += {'usb net redir': usbredir} 4802summary_info += {'OpenGL support (epoxy)': opengl} 4803summary_info += {'GBM': gbm} 4804summary_info += {'libiscsi support': libiscsi} 4805summary_info += {'libnfs support': libnfs} 4806if host_os == 'windows' 4807 if have_ga 4808 summary_info += {'QGA VSS support': have_qga_vss} 4809 endif 4810endif 4811summary_info += {'seccomp support': seccomp} 4812summary_info += {'GlusterFS support': glusterfs} 4813summary_info += {'hv-balloon support': hv_balloon} 4814summary_info += {'TPM support': have_tpm} 4815summary_info += {'libssh support': libssh} 4816summary_info += {'lzo support': lzo} 4817summary_info += {'snappy support': snappy} 4818summary_info += {'bzip2 support': libbzip2} 4819summary_info += {'lzfse support': liblzfse} 4820summary_info += {'zstd support': zstd} 4821summary_info += {'Query Processing Library support': qpl} 4822summary_info += {'UADK Library support': uadk} 4823summary_info += {'qatzip support': qatzip} 4824summary_info += {'NUMA host support': numa} 4825summary_info += {'capstone': capstone} 4826summary_info += {'libpmem support': libpmem} 4827summary_info += {'libdaxctl support': libdaxctl} 4828summary_info += {'libcbor support': libcbor} 4829summary_info += {'libudev': libudev} 4830# Dummy dependency, keep .found() 4831summary_info += {'FUSE lseek': fuse_lseek.found()} 4832summary_info += {'selinux': selinux} 4833summary_info += {'libdw': libdw} 4834if host_os == 'freebsd' 4835 summary_info += {'libinotify-kqueue': inotify} 4836endif 4837summary(summary_info, bool_yn: true, section: 'Dependencies') 4838 4839if host_arch == 'unknown' 4840 message() 4841 warning('UNSUPPORTED HOST CPU') 4842 message() 4843 message('Support for CPU host architecture ' + cpu + ' is not currently') 4844 message('maintained. The QEMU project does not guarantee that QEMU will') 4845 message('compile or work on this host CPU. You can help by volunteering') 4846 message('to maintain it and providing a build host for our continuous') 4847 message('integration setup.') 4848 if get_option('tcg').allowed() and target_dirs.length() > 0 4849 message() 4850 message('configure has succeeded and you can continue to build, but') 4851 message('QEMU will use a slow interpreter to emulate the target CPU.') 4852 endif 4853elif host_long_bits < 64 4854 message() 4855 warning('DEPRECATED HOST CPU') 4856 message() 4857 message('Support for 32-bit CPU host architecture ' + cpu + ' is going') 4858 message('to be dropped in a future QEMU release.') 4859endif 4860 4861if not supported_oses.contains(host_os) 4862 message() 4863 warning('UNSUPPORTED HOST OS') 4864 message() 4865 message('Support for host OS ' + host_os + 'is not currently maintained.') 4866 message('configure has succeeded and you can continue to build, but') 4867 message('the QEMU project does not guarantee that QEMU will compile or') 4868 message('work on this operating system. You can help by volunteering') 4869 message('to maintain it and providing a build host for our continuous') 4870 message('integration setup. This will ensure that future versions of QEMU') 4871 message('will keep working on ' + host_os + '.') 4872endif 4873 4874if host_arch == 'unknown' or not supported_oses.contains(host_os) 4875 message() 4876 message('If you want to help supporting QEMU on this platform, please') 4877 message('contact the developers at qemu-devel@nongnu.org.') 4878endif 4879 4880actually_reloc = get_option('relocatable') 4881# check if get_relocated_path() is actually able to relocate paths 4882if get_option('relocatable') and \ 4883 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4884 message() 4885 warning('bindir not included within prefix, the installation will not be relocatable.') 4886 actually_reloc = false 4887endif 4888if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4889 if host_os == 'windows' 4890 message() 4891 warning('Windows installs should usually be relocatable.') 4892 endif 4893 message() 4894 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4895 message('Use --disable-relocatable to remove this warning.') 4896endif 4897