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