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