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