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