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