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