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