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/hvf', 3634 'accel/kvm', 3635 'audio', 3636 'backends', 3637 'backends/tpm', 3638 'ebpf', 3639 'hw/9pfs', 3640 'hw/acpi', 3641 'hw/adc', 3642 'hw/alpha', 3643 'hw/arm', 3644 'hw/audio', 3645 'hw/block', 3646 'hw/char', 3647 'hw/display', 3648 'hw/dma', 3649 'hw/fsi', 3650 'hw/hyperv', 3651 'hw/i2c', 3652 'hw/i386', 3653 'hw/i386/xen', 3654 'hw/i386/kvm', 3655 'hw/ide', 3656 'hw/input', 3657 'hw/intc', 3658 'hw/isa', 3659 'hw/mem', 3660 'hw/mips', 3661 'hw/misc', 3662 'hw/misc/macio', 3663 'hw/net', 3664 'hw/net/can', 3665 'hw/nubus', 3666 'hw/nvme', 3667 'hw/nvram', 3668 'hw/pci', 3669 'hw/pci-host', 3670 'hw/ppc', 3671 'hw/rtc', 3672 'hw/riscv', 3673 'hw/s390x', 3674 'hw/scsi', 3675 'hw/sd', 3676 'hw/sensor', 3677 'hw/sh4', 3678 'hw/sparc', 3679 'hw/sparc64', 3680 'hw/ssi', 3681 'hw/timer', 3682 'hw/tpm', 3683 'hw/uefi', 3684 'hw/ufs', 3685 'hw/usb', 3686 'hw/vfio', 3687 'hw/vfio-user', 3688 'hw/virtio', 3689 'hw/vmapple', 3690 'hw/watchdog', 3691 'hw/xen', 3692 'hw/gpio', 3693 'migration', 3694 'net', 3695 'system', 3696 'ui', 3697 'hw/remote', 3698 ] 3699endif 3700if have_system or have_user 3701 trace_events_subdirs += [ 3702 'accel/tcg', 3703 'hw/core', 3704 'target/arm', 3705 'target/arm/hvf', 3706 'target/hppa', 3707 'target/i386', 3708 'target/i386/kvm', 3709 'target/loongarch', 3710 'target/mips/tcg', 3711 'target/ppc', 3712 'target/riscv', 3713 'target/s390x', 3714 'target/s390x/kvm', 3715 'target/sparc', 3716 ] 3717endif 3718 3719################### 3720# Collect sources # 3721################### 3722 3723authz_ss = ss.source_set() 3724blockdev_ss = ss.source_set() 3725block_ss = ss.source_set() 3726chardev_ss = ss.source_set() 3727common_ss = ss.source_set() 3728crypto_ss = ss.source_set() 3729hwcore_ss = ss.source_set() 3730io_ss = ss.source_set() 3731qmp_ss = ss.source_set() 3732qom_ss = ss.source_set() 3733system_ss = ss.source_set() 3734specific_fuzz_ss = ss.source_set() 3735specific_ss = ss.source_set() 3736rust_devices_ss = ss.source_set() 3737stub_ss = ss.source_set() 3738trace_ss = ss.source_set() 3739user_ss = ss.source_set() 3740util_ss = ss.source_set() 3741 3742# accel modules 3743qtest_module_ss = ss.source_set() 3744 3745modules = {} 3746target_modules = {} 3747plugin_modules = [] 3748hw_arch = {} 3749target_arch = {} 3750target_system_arch = {} 3751target_user_arch = {} 3752hw_common_arch = {} 3753target_common_arch = {} 3754target_common_system_arch = {} 3755 3756# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3757# that is filled in by qapi/. 3758subdir('qapi') 3759subdir('qobject') 3760subdir('stubs') 3761subdir('trace') 3762subdir('util') 3763subdir('qom') 3764subdir('authz') 3765subdir('crypto') 3766subdir('ui') 3767subdir('gdbstub') 3768if have_system 3769 subdir('hw') 3770else 3771 subdir('hw/core') 3772endif 3773 3774if enable_modules 3775 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3776 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3777endif 3778 3779qom_ss = qom_ss.apply({}) 3780libqom = static_library('qom', qom_ss.sources() + genh, 3781 dependencies: [qom_ss.dependencies()], 3782 build_by_default: false) 3783qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3784 dependencies: qom_ss.dependencies()) 3785 3786event_loop_base = files('event-loop-base.c') 3787event_loop_base = static_library('event-loop-base', 3788 sources: event_loop_base + genh, 3789 build_by_default: false) 3790event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3791 dependencies: [qom]) 3792 3793stub_ss = stub_ss.apply({}) 3794 3795util_ss.add_all(trace_ss) 3796util_ss = util_ss.apply({}) 3797libqemuutil = static_library('qemuutil', 3798 build_by_default: false, 3799 sources: util_ss.sources() + stub_ss.sources() + genh, 3800 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3801qemuutil_deps = [event_loop_base] 3802if host_os != 'windows' 3803 qemuutil_deps += [rt] 3804endif 3805qemuutil = declare_dependency(link_with: libqemuutil, 3806 sources: genh + version_res, 3807 dependencies: qemuutil_deps) 3808 3809if have_system or have_user 3810 decodetree = generator(find_program('scripts/decodetree.py'), 3811 output: 'decode-@BASENAME@.c.inc', 3812 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3813 subdir('libdecnumber') 3814 subdir('target') 3815endif 3816 3817subdir('audio') 3818subdir('io') 3819subdir('chardev') 3820subdir('fsdev') 3821subdir('dump') 3822 3823if have_block 3824 block_ss.add(files( 3825 'block.c', 3826 'blockjob.c', 3827 'job.c', 3828 'qemu-io-cmds.c', 3829 )) 3830 if config_host_data.get('CONFIG_REPLICATION') 3831 block_ss.add(files('replication.c')) 3832 endif 3833 3834 subdir('nbd') 3835 subdir('scsi') 3836 subdir('block') 3837 3838 blockdev_ss.add(files( 3839 'blockdev.c', 3840 'blockdev-nbd.c', 3841 'iothread.c', 3842 'job-qmp.c', 3843 )) 3844 3845 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3846 # os-win32.c does not 3847 if host_os == 'windows' 3848 system_ss.add(files('os-win32.c')) 3849 elif host_os == 'emscripten' 3850 blockdev_ss.add(files('os-wasm.c')) 3851 else 3852 blockdev_ss.add(files('os-posix.c')) 3853 endif 3854endif 3855 3856common_ss.add(files('cpu-common.c')) 3857specific_ss.add(files('cpu-target.c')) 3858 3859subdir('system') 3860 3861# Work around a gcc bug/misfeature wherein constant propagation looks 3862# through an alias: 3863# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3864# to guess that a const variable is always zero. Without lto, this is 3865# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3866# without lto, not even the alias is required -- we simply use different 3867# declarations in different compilation units. 3868pagevary = files('page-vary-common.c') 3869if get_option('b_lto') 3870 pagevary_flags = ['-fno-lto'] 3871 if get_option('cfi') 3872 pagevary_flags += '-fno-sanitize=cfi-icall' 3873 endif 3874 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3875 c_args: pagevary_flags) 3876 pagevary = declare_dependency(link_with: pagevary) 3877endif 3878common_ss.add(pagevary) 3879specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3880 3881common_ss.add(files('target-info.c')) 3882specific_ss.add(files('target-info-stub.c')) 3883 3884subdir('backends') 3885subdir('disas') 3886subdir('migration') 3887subdir('monitor') 3888subdir('net') 3889subdir('replay') 3890subdir('semihosting') 3891subdir('stats') 3892subdir('tcg') 3893subdir('fpu') 3894subdir('accel') 3895subdir('plugins') 3896subdir('ebpf') 3897 3898if 'CONFIG_TCG' in config_all_accel 3899 subdir('contrib/plugins') 3900endif 3901 3902common_user_inc = [] 3903 3904subdir('common-user') 3905subdir('bsd-user') 3906subdir('linux-user') 3907 3908# needed for fuzzing binaries 3909subdir('tests/qtest/libqos') 3910subdir('tests/qtest/fuzz') 3911 3912# accel modules 3913target_modules += { 'accel' : { 'qtest': qtest_module_ss }} 3914 3915############################################## 3916# Internal static_libraries and dependencies # 3917############################################## 3918 3919modinfo_collect = find_program('scripts/modinfo-collect.py') 3920modinfo_generate = find_program('scripts/modinfo-generate.py') 3921modinfo_files = [] 3922 3923block_mods = [] 3924system_mods = [] 3925emulator_modules = [] 3926foreach d, list : modules 3927 if not (d == 'block' ? have_block : have_system) 3928 continue 3929 endif 3930 3931 foreach m, module_ss : list 3932 if enable_modules 3933 module_ss.add(modulecommon) 3934 module_ss = module_ss.apply(config_all_devices, strict: false) 3935 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3936 dependencies: module_ss.dependencies(), pic: true) 3937 if d == 'block' 3938 block_mods += sl 3939 else 3940 system_mods += sl 3941 endif 3942 emulator_modules += shared_module(sl.name(), 3943 name_prefix: '', 3944 objects: sl.extract_all_objects(recursive: false), 3945 dependencies: module_ss.dependencies(), 3946 install: true, 3947 install_dir: qemu_moddir) 3948 if module_ss.sources() != [] 3949 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3950 output: d + '-' + m + '.modinfo', 3951 input: sl.extract_all_objects(recursive: true), 3952 capture: true, 3953 command: [modinfo_collect, '@INPUT@']) 3954 endif 3955 else 3956 if d == 'block' 3957 block_ss.add_all(module_ss) 3958 else 3959 system_ss.add_all(module_ss) 3960 endif 3961 endif 3962 endforeach 3963endforeach 3964 3965foreach d, list : target_modules 3966 foreach m, module_ss : list 3967 if enable_modules 3968 module_ss.add(modulecommon) 3969 foreach target : target_dirs 3970 if target.endswith('-softmmu') 3971 config_target = config_target_mak[target] 3972 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3973 c_args = ['-DCOMPILING_PER_TARGET', 3974 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3975 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3976 target_module_ss = module_ss.apply(config_target, strict: false) 3977 if target_module_ss.sources() != [] 3978 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3979 sl = static_library(module_name, 3980 [genh, target_module_ss.sources()], 3981 dependencies: target_module_ss.dependencies(), 3982 include_directories: target_inc, 3983 c_args: c_args, 3984 pic: true) 3985 system_mods += sl 3986 emulator_modules += shared_module(sl.name(), 3987 name_prefix: '', 3988 objects: sl.extract_all_objects(recursive: false), 3989 dependencies: target_module_ss.dependencies(), 3990 install: true, 3991 install_dir: qemu_moddir) 3992 modinfo_files += custom_target(module_name + '.modinfo', 3993 output: module_name + '.modinfo', 3994 input: sl.extract_all_objects(recursive: true), 3995 capture: true, 3996 command: [modinfo_collect, '--target', target, '@INPUT@']) 3997 endif 3998 endif 3999 endforeach 4000 else 4001 specific_ss.add_all(module_ss) 4002 endif 4003 endforeach 4004endforeach 4005 4006if enable_modules 4007 foreach target : target_dirs 4008 if target.endswith('-softmmu') 4009 config_target = config_target_mak[target] 4010 config_devices_mak = target + '-config-devices.mak' 4011 modinfo_src = custom_target('modinfo-' + target + '.c', 4012 output: 'modinfo-' + target + '.c', 4013 input: modinfo_files, 4014 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 4015 capture: true) 4016 4017 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 4018 modinfo_dep = declare_dependency(link_with: modinfo_lib) 4019 4020 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 4021 hw_arch[arch].add(modinfo_dep) 4022 endif 4023 endforeach 4024 4025 if emulator_modules.length() > 0 4026 alias_target('modules', emulator_modules) 4027 endif 4028endif 4029 4030nm = find_program('nm') 4031undefsym = find_program('scripts/undefsym.py') 4032block_syms = custom_target('block.syms', output: 'block.syms', 4033 input: [libqemuutil, block_mods], 4034 capture: true, 4035 command: [undefsym, nm, '@INPUT@']) 4036qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 4037 input: [libqemuutil, system_mods], 4038 capture: true, 4039 command: [undefsym, nm, '@INPUT@']) 4040 4041authz_ss = authz_ss.apply({}) 4042libauthz = static_library('authz', authz_ss.sources() + genh, 4043 dependencies: [authz_ss.dependencies()], 4044 build_by_default: false) 4045 4046authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 4047 dependencies: [authz_ss.dependencies(), qom]) 4048 4049crypto_ss = crypto_ss.apply({}) 4050libcrypto = static_library('crypto', crypto_ss.sources() + genh, 4051 dependencies: [crypto_ss.dependencies()], 4052 build_by_default: false) 4053 4054crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 4055 dependencies: [crypto_ss.dependencies(), authz, qom]) 4056 4057io_ss = io_ss.apply({}) 4058libio = static_library('io', io_ss.sources() + genh, 4059 dependencies: [io_ss.dependencies()], 4060 link_with: libqemuutil, 4061 build_by_default: false) 4062 4063io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 4064 dependencies: [io_ss.dependencies(), crypto, qom]) 4065 4066libmigration = static_library('migration', sources: migration_files + genh, 4067 build_by_default: false) 4068migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 4069 dependencies: [qom, io]) 4070system_ss.add(migration) 4071 4072block_ss = block_ss.apply({}) 4073libblock = static_library('block', block_ss.sources() + genh, 4074 dependencies: block_ss.dependencies(), 4075 build_by_default: false) 4076 4077block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 4078 dependencies: [block_ss.dependencies(), crypto, io]) 4079 4080blockdev_ss = blockdev_ss.apply({}) 4081libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 4082 dependencies: blockdev_ss.dependencies(), 4083 build_by_default: false) 4084 4085blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 4086 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 4087 4088qmp_ss = qmp_ss.apply({}) 4089libqmp = static_library('qmp', qmp_ss.sources() + genh, 4090 dependencies: qmp_ss.dependencies(), 4091 build_by_default: false) 4092 4093qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 4094 dependencies: qmp_ss.dependencies()) 4095 4096libchardev = static_library('chardev', chardev_ss.sources() + genh, 4097 dependencies: chardev_ss.dependencies(), 4098 build_by_default: false) 4099 4100chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 4101 dependencies: [chardev_ss.dependencies(), io]) 4102 4103hwcore_ss = hwcore_ss.apply({}) 4104libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 4105 build_by_default: false) 4106hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 4107common_ss.add(hwcore) 4108 4109########### 4110# Targets # 4111########### 4112 4113system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 4114common_ss.add(qom, qemuutil) 4115 4116libuser = static_library('user', 4117 user_ss.all_sources() + genh, 4118 c_args: ['-DCONFIG_USER_ONLY', 4119 '-DCOMPILING_SYSTEM_VS_USER'], 4120 include_directories: common_user_inc, 4121 dependencies: user_ss.all_dependencies(), 4122 build_by_default: false) 4123 4124libsystem = static_library('system', 4125 system_ss.all_sources() + genh, 4126 c_args: ['-DCONFIG_SOFTMMU', 4127 '-DCOMPILING_SYSTEM_VS_USER'], 4128 dependencies: system_ss.all_dependencies(), 4129 build_by_default: false) 4130 4131# Note that this library is never used directly (only through extract_objects) 4132# and is not built by default; therefore, source files not used by the build 4133# configuration will be in build.ninja, but are never built by default. 4134common_all = static_library('common', 4135 build_by_default: false, 4136 sources: common_ss.all_sources() + genh, 4137 implicit_include_directories: false, 4138 dependencies: common_ss.all_dependencies()) 4139 4140# construct common libraries per base architecture 4141target_common_arch_libs = {} 4142target_common_system_arch_libs = {} 4143foreach target_base_arch, config_base_arch : config_base_arch_mak 4144 target_inc = [include_directories('target' / target_base_arch)] 4145 inc = [common_user_inc + target_inc] 4146 4147 target_common = common_ss.apply(config_base_arch, strict: false) 4148 target_system = system_ss.apply(config_base_arch, strict: false) 4149 target_user = user_ss.apply(config_base_arch, strict: false) 4150 common_deps = [] 4151 system_deps = [] 4152 user_deps = [] 4153 foreach dep: target_common.dependencies() 4154 common_deps += dep.partial_dependency(compile_args: true, includes: true) 4155 endforeach 4156 foreach dep: target_system.dependencies() 4157 system_deps += dep.partial_dependency(compile_args: true, includes: true) 4158 endforeach 4159 foreach dep: target_user.dependencies() 4160 user_deps += dep.partial_dependency(compile_args: true, includes: true) 4161 endforeach 4162 4163 # prevent common code to access cpu compile time definition, 4164 # but still allow access to cpu.h 4165 target_c_args = ['-DCPU_DEFS_H'] 4166 target_system_c_args = target_c_args + ['-DCOMPILING_SYSTEM_VS_USER', '-DCONFIG_SOFTMMU'] 4167 4168 if target_base_arch in target_common_arch 4169 src = target_common_arch[target_base_arch] 4170 lib = static_library( 4171 'common_' + target_base_arch, 4172 build_by_default: false, 4173 sources: src.all_sources() + genh, 4174 include_directories: inc, 4175 c_args: target_c_args, 4176 dependencies: src.all_dependencies() + common_deps + 4177 system_deps + user_deps) 4178 target_common_arch_libs += {target_base_arch: lib} 4179 endif 4180 4181 # merge hw_common_arch in target_common_system_arch 4182 if target_base_arch in hw_common_arch 4183 hw_src = hw_common_arch[target_base_arch] 4184 if target_base_arch in target_common_system_arch 4185 target_common_system_arch[target_base_arch].add_all(hw_src) 4186 else 4187 target_common_system_arch += {target_base_arch: hw_src} 4188 endif 4189 endif 4190 4191 if target_base_arch in target_common_system_arch 4192 src = target_common_system_arch[target_base_arch] 4193 lib = static_library( 4194 'system_' + target_base_arch, 4195 build_by_default: false, 4196 sources: src.all_sources() + genh, 4197 include_directories: inc, 4198 c_args: target_system_c_args, 4199 dependencies: src.all_dependencies() + common_deps + system_deps) 4200 target_common_system_arch_libs += {target_base_arch: lib} 4201 endif 4202endforeach 4203 4204if have_rust 4205 bindings_incdir = include_directories('.', 'include') 4206 # We would like to use --generate-cstr, but it is only available 4207 # starting with bindgen 0.66.0. The oldest supported versions 4208 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file. 4209 bindgen_args_common = [ 4210 '--disable-header-comment', 4211 '--raw-line', '// @generated', 4212 '--ctypes-prefix', 'std::os::raw', 4213 '--generate-block', 4214 '--impl-debug', 4215 '--no-doc-comments', 4216 '--with-derive-default', 4217 '--no-layout-tests', 4218 '--no-prepend-enum-name', 4219 '--allowlist-file', meson.project_source_root() + '/include/.*', 4220 '--allowlist-file', meson.project_source_root() + '/.*', 4221 '--allowlist-file', meson.project_build_root() + '/.*' 4222 ] 4223 if not rustfmt.found() 4224 if bindgen.version().version_compare('<0.65.0') 4225 bindgen_args_common += ['--no-rustfmt-bindings'] 4226 else 4227 bindgen_args_common += ['--formatter', 'none'] 4228 endif 4229 endif 4230 if bindgen.version().version_compare('>=0.66.0') 4231 bindgen_args_common += ['--rust-target', '1.59'] 4232 endif 4233 if bindgen.version().version_compare('<0.61.0') 4234 # default in 0.61+ 4235 bindgen_args_common += ['--size_t-is-usize'] 4236 else 4237 bindgen_args_common += ['--merge-extern-blocks'] 4238 endif 4239 subdir('rust') 4240endif 4241 4242 4243feature_to_c = find_program('scripts/feature_to_c.py') 4244rust_root_crate = find_program('scripts/rust/rust_root_crate.sh') 4245 4246if host_os == 'darwin' 4247 entitlement = find_program('scripts/entitlement.sh') 4248endif 4249 4250traceable = [] 4251emulators = {} 4252foreach target : target_dirs 4253 config_target = config_target_mak[target] 4254 target_name = config_target['TARGET_NAME'] 4255 target_base_arch = config_target['TARGET_BASE_ARCH'] 4256 arch_srcs = [config_target_h[target]] 4257 arch_deps = [] 4258 c_args = ['-DCOMPILING_PER_TARGET', 4259 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4260 ] 4261 link_args = emulator_link_args 4262 4263 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4264 if host_os == 'linux' 4265 target_inc += include_directories('linux-headers', is_system: true) 4266 endif 4267 if target.endswith('-softmmu') 4268 target_type='system' 4269 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4270 arch_srcs += t.sources() 4271 arch_deps += t.dependencies() 4272 4273 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4274 if hw_arch.has_key(hw_dir) 4275 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4276 arch_srcs += hw.sources() 4277 arch_deps += hw.dependencies() 4278 endif 4279 4280 c_args += ['-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4281 arch_srcs += config_devices_h[target] 4282 link_args += ['@block.syms', '@qemu.syms'] 4283 else 4284 abi = config_target['TARGET_ABI_DIR'] 4285 target_type='user' 4286 target_inc += common_user_inc 4287 if target_base_arch in target_user_arch 4288 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4289 arch_srcs += t.sources() 4290 arch_deps += t.dependencies() 4291 endif 4292 if 'CONFIG_LINUX_USER' in config_target 4293 base_dir = 'linux-user' 4294 endif 4295 if 'CONFIG_BSD_USER' in config_target 4296 base_dir = 'bsd-user' 4297 target_inc += include_directories('bsd-user/' / host_os) 4298 target_inc += include_directories('bsd-user/host/' / host_arch) 4299 dir = base_dir / abi 4300 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4301 endif 4302 target_inc += include_directories( 4303 base_dir, 4304 base_dir / abi, 4305 ) 4306 if 'CONFIG_LINUX_USER' in config_target 4307 dir = base_dir / abi 4308 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4309 if config_target.has_key('TARGET_SYSTBL_ABI') 4310 arch_srcs += \ 4311 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4312 extra_args : config_target['TARGET_SYSTBL_ABI']) 4313 endif 4314 endif 4315 endif 4316 4317 if 'TARGET_XML_FILES' in config_target 4318 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4319 output: target + '-gdbstub-xml.c', 4320 input: files(config_target['TARGET_XML_FILES'].split()), 4321 command: [feature_to_c, '@INPUT@'], 4322 capture: true) 4323 arch_srcs += gdbstub_xml 4324 endif 4325 4326 t = target_arch[target_base_arch].apply(config_target, strict: false) 4327 arch_srcs += t.sources() 4328 arch_deps += t.dependencies() 4329 4330 target_common = common_ss.apply(config_target, strict: false) 4331 objects = [common_all.extract_objects(target_common.sources())] 4332 arch_deps += target_common.dependencies() 4333 if target_base_arch in target_common_arch_libs 4334 src = target_common_arch[target_base_arch].apply(config_target, strict: false) 4335 lib = target_common_arch_libs[target_base_arch] 4336 objects += lib.extract_objects(src.sources()) 4337 arch_deps += src.dependencies() 4338 endif 4339 if target_type == 'system' 4340 src = system_ss.apply(config_target, strict: false) 4341 objects += libsystem.extract_objects(src.sources()) 4342 arch_deps += src.dependencies() 4343 endif 4344 if target_type == 'user' 4345 src = user_ss.apply(config_target, strict: false) 4346 objects += libuser.extract_objects(src.sources()) 4347 arch_deps += src.dependencies() 4348 endif 4349 if target_type == 'system' and target_base_arch in target_common_system_arch_libs 4350 src = target_common_system_arch[target_base_arch].apply(config_target, strict: false) 4351 lib = target_common_system_arch_libs[target_base_arch] 4352 objects += lib.extract_objects(src.sources()) 4353 arch_deps += src.dependencies() 4354 endif 4355 4356 target_specific = specific_ss.apply(config_target, strict: false) 4357 arch_srcs += target_specific.sources() 4358 arch_deps += target_specific.dependencies() 4359 4360 if have_rust and target_type == 'system' 4361 target_rust = rust_devices_ss.apply(config_target, strict: false) 4362 crates = [] 4363 foreach dep : target_rust.dependencies() 4364 crates += dep.get_variable('crate') 4365 endforeach 4366 if crates.length() > 0 4367 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4368 output: 'rust_' + target.underscorify() + '.rs', 4369 command: [rust_root_crate, crates], 4370 capture: true, 4371 build_by_default: true, 4372 build_always_stale: true) 4373 rlib = static_library('rust_' + target.underscorify(), 4374 structured_sources([], {'.': rlib_rs}), 4375 dependencies: target_rust.dependencies(), 4376 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4377 rust_abi: 'c') 4378 arch_deps += declare_dependency(link_whole: [rlib]) 4379 endif 4380 endif 4381 4382 # allow using headers from the dependencies but do not include the sources, 4383 # because this emulator only needs those in "objects". For external 4384 # dependencies, the full dependency is included below in the executable. 4385 lib_deps = [] 4386 foreach dep : arch_deps 4387 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4388 endforeach 4389 4390 lib = static_library('qemu-' + target, 4391 sources: arch_srcs + genh, 4392 dependencies: lib_deps, 4393 objects: objects, 4394 include_directories: target_inc, 4395 c_args: c_args, 4396 build_by_default: false) 4397 4398 if target.endswith('-softmmu') 4399 execs = [{ 4400 'name': 'qemu-system-' + target_name, 4401 'win_subsystem': 'console', 4402 'sources': files('system/main.c'), 4403 'dependencies': [sdl] 4404 }] 4405 if host_os == 'windows' and (sdl.found() or gtk.found()) 4406 execs += [{ 4407 'name': 'qemu-system-' + target_name + 'w', 4408 'win_subsystem': 'windows', 4409 'sources': files('system/main.c'), 4410 'dependencies': [sdl] 4411 }] 4412 endif 4413 if get_option('fuzzing') 4414 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4415 execs += [{ 4416 'name': 'qemu-fuzz-' + target_name, 4417 'win_subsystem': 'console', 4418 'sources': specific_fuzz.sources(), 4419 'dependencies': specific_fuzz.dependencies(), 4420 }] 4421 endif 4422 else 4423 execs = [{ 4424 'name': 'qemu-' + target_name, 4425 'win_subsystem': 'console', 4426 'sources': [], 4427 'dependencies': [] 4428 }] 4429 endif 4430 foreach exe: execs 4431 exe_name = exe['name'] 4432 if host_os == 'darwin' 4433 exe_name += '-unsigned' 4434 endif 4435 4436 emulator = executable(exe_name, exe['sources'], 4437 install: true, 4438 c_args: c_args, 4439 dependencies: arch_deps + exe['dependencies'], 4440 objects: lib.extract_all_objects(recursive: true), 4441 link_depends: [block_syms, qemu_syms], 4442 link_args: link_args, 4443 win_subsystem: exe['win_subsystem']) 4444 4445 if host_os == 'darwin' 4446 icon = 'pc-bios/qemu.rsrc' 4447 build_input = [emulator, files(icon)] 4448 install_input = [ 4449 get_option('bindir') / exe_name, 4450 meson.current_source_dir() / icon 4451 ] 4452 if 'CONFIG_HVF' in config_target 4453 entitlements = 'accel/hvf/entitlements.plist' 4454 build_input += files(entitlements) 4455 install_input += meson.current_source_dir() / entitlements 4456 endif 4457 4458 emulators += {exe['name'] : custom_target(exe['name'], 4459 input: build_input, 4460 output: exe['name'], 4461 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4462 } 4463 4464 meson.add_install_script(entitlement, '--install', 4465 get_option('bindir') / exe['name'], 4466 install_input) 4467 else 4468 emulators += {exe['name']: emulator} 4469 endif 4470 4471 traceable += [{ 4472 'exe': exe['name'], 4473 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4474 }] 4475 4476 endforeach 4477endforeach 4478 4479# Other build targets 4480 4481if get_option('plugins') 4482 install_headers('include/qemu/qemu-plugin.h') 4483 if host_os == 'windows' 4484 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4485 # so that plugin authors can compile against it. 4486 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4487 endif 4488endif 4489 4490subdir('qga') 4491 4492# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4493# when we don't build tools or system 4494if xkbcommon.found() 4495 # used for the update-keymaps target, so include rules even if !have_tools 4496 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4497 dependencies: [qemuutil, xkbcommon], install: have_tools) 4498endif 4499 4500if have_tools 4501 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4502 link_args: '@block.syms', link_depends: block_syms, 4503 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4504 qemu_io = executable('qemu-io', files('qemu-io.c'), 4505 link_args: '@block.syms', link_depends: block_syms, 4506 dependencies: [block, qemuutil], install: true) 4507 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4508 link_args: '@block.syms', link_depends: block_syms, 4509 dependencies: [blockdev, qemuutil, selinux], 4510 install: true) 4511 4512 subdir('storage-daemon') 4513 4514 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4515 traceable += [{ 4516 'exe': exe, 4517 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4518 }] 4519 endforeach 4520 4521 subdir('contrib/elf2dmp') 4522 4523 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4524 dependencies: [qemuutil, rt], 4525 install: true) 4526 4527 if have_vhost_user 4528 subdir('contrib/vhost-user-blk') 4529 subdir('contrib/vhost-user-gpu') 4530 subdir('contrib/vhost-user-input') 4531 subdir('contrib/vhost-user-scsi') 4532 endif 4533 4534 if host_os == 'linux' 4535 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4536 dependencies: [qemuutil, libcap_ng], 4537 install: true, 4538 install_dir: get_option('libexecdir')) 4539 4540 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4541 dependencies: [authz, crypto, io, qom, qemuutil, 4542 libcap_ng, mpathpersist], 4543 install: true) 4544 4545 if cpu in ['x86', 'x86_64'] 4546 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4547 dependencies: [authz, crypto, io, qom, qemuutil, 4548 libcap_ng, mpathpersist], 4549 install: true) 4550 endif 4551 endif 4552 4553 if have_ivshmem 4554 subdir('contrib/ivshmem-client') 4555 subdir('contrib/ivshmem-server') 4556 endif 4557endif 4558 4559if stap.found() 4560 foreach t: traceable 4561 foreach stp: [ 4562 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4563 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4564 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4565 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4566 ] 4567 cmd = [ 4568 tracetool, '--group=all', '--format=' + stp['fmt'], 4569 '--binary=' + stp['bin'], 4570 '--probe-prefix=' + t['probe-prefix'], 4571 '@INPUT@', '@OUTPUT@' 4572 ] 4573 4574 custom_target(t['exe'] + stp['ext'], 4575 input: trace_events_all, 4576 output: t['exe'] + stp['ext'], 4577 install: stp['install'], 4578 install_dir: get_option('datadir') / 'systemtap/tapset', 4579 command: cmd, 4580 depend_files: tracetool_depends) 4581 endforeach 4582 endforeach 4583endif 4584 4585subdir('scripts') 4586subdir('tools') 4587subdir('pc-bios') 4588subdir('docs') 4589# Tests are disabled on emscripten because they rely on host features that aren't 4590# supported by emscripten (e.g. fork and unix socket). 4591if host_os != 'emscripten' 4592 subdir('tests') 4593endif 4594if gtk.found() 4595 subdir('po') 4596endif 4597 4598if host_machine.system() == 'windows' 4599 nsis_cmd = [ 4600 find_program('scripts/nsis.py'), 4601 '@OUTPUT@', 4602 get_option('prefix'), 4603 meson.current_source_dir(), 4604 glib_pc.get_variable('bindir'), 4605 host_machine.cpu(), 4606 '--', 4607 '-DDISPLAYVERSION=' + meson.project_version(), 4608 ] 4609 if build_docs 4610 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4611 endif 4612 if gtk.found() 4613 nsis_cmd += '-DCONFIG_GTK=y' 4614 endif 4615 4616 nsis = custom_target('nsis', 4617 output: 'qemu-setup-' + meson.project_version() + '.exe', 4618 input: files('qemu.nsi'), 4619 build_always_stale: true, 4620 command: nsis_cmd + ['@INPUT@']) 4621 alias_target('installer', nsis) 4622endif 4623 4624######################### 4625# Configuration summary # 4626######################### 4627 4628# Build environment 4629summary_info = {} 4630summary_info += {'Build directory': meson.current_build_dir()} 4631summary_info += {'Source path': meson.current_source_dir()} 4632summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4633summary(summary_info, bool_yn: true, section: 'Build environment') 4634 4635# Directories 4636summary_info += {'Install prefix': get_option('prefix')} 4637summary_info += {'BIOS directory': qemu_datadir} 4638pathsep = host_os == 'windows' ? ';' : ':' 4639summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4640summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4641summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4642summary_info += {'module directory': qemu_moddir} 4643summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4644summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4645summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4646if host_os != 'windows' 4647 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4648 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4649else 4650 summary_info += {'local state directory': 'queried at runtime'} 4651endif 4652summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4653summary(summary_info, bool_yn: true, section: 'Directories') 4654 4655# Host binaries 4656summary_info = {} 4657summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4658summary_info += {'sphinx-build': sphinx_build} 4659 4660# FIXME: the [binaries] section of machine files, which can be probed 4661# with find_program(), would be great for passing gdb and genisoimage 4662# paths from configure to Meson. However, there seems to be no way to 4663# hide a program (for example if gdb is too old). 4664if config_host.has_key('GDB') 4665 summary_info += {'gdb': config_host['GDB']} 4666endif 4667summary_info += {'iasl': iasl} 4668summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4669if host_os == 'windows' and have_ga 4670 summary_info += {'wixl': wixl} 4671endif 4672if slirp.found() and have_system 4673 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4674endif 4675summary(summary_info, bool_yn: true, section: 'Host binaries') 4676 4677# Configurable features 4678summary_info = {} 4679summary_info += {'Documentation': build_docs} 4680summary_info += {'system-mode emulation': have_system} 4681summary_info += {'user-mode emulation': have_user} 4682summary_info += {'block layer': have_block} 4683summary_info += {'Install blobs': get_option('install_blobs')} 4684summary_info += {'module support': enable_modules} 4685if enable_modules 4686 summary_info += {'alternative module path': get_option('module_upgrades')} 4687endif 4688summary_info += {'fuzzing support': get_option('fuzzing')} 4689if have_system 4690 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4691endif 4692summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4693if 'simple' in get_option('trace_backends') 4694 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4695endif 4696summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4697summary_info += {'Relocatable install': get_option('relocatable')} 4698summary_info += {'vhost-kernel support': have_vhost_kernel} 4699summary_info += {'vhost-net support': have_vhost_net} 4700summary_info += {'vhost-user support': have_vhost_user} 4701summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4702summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4703summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4704summary_info += {'build guest agent': have_ga} 4705summary(summary_info, bool_yn: true, section: 'Configurable features') 4706 4707# Compilation information 4708summary_info = {} 4709summary_info += {'host CPU': cpu} 4710summary_info += {'host endianness': build_machine.endian()} 4711summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4712summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4713if 'cpp' in all_languages 4714 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4715else 4716 summary_info += {'C++ compiler': false} 4717endif 4718if 'objc' in all_languages 4719 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4720else 4721 summary_info += {'Objective-C compiler': false} 4722endif 4723summary_info += {'Rust support': have_rust} 4724if have_rust 4725 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4726 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4727 summary_info += {'rustc version': rustc.version()} 4728 summary_info += {'rustdoc': rustdoc} 4729 summary_info += {'bindgen': bindgen.full_path()} 4730 summary_info += {'bindgen version': bindgen.version()} 4731endif 4732option_cflags = (get_option('debug') ? ['-g'] : []) 4733if get_option('optimization') != 'plain' 4734 option_cflags += ['-O' + get_option('optimization')] 4735endif 4736summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4737if 'cpp' in all_languages 4738 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4739endif 4740if 'objc' in all_languages 4741 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4742endif 4743link_args = get_option('c_link_args') 4744if link_args.length() > 0 4745 summary_info += {'LDFLAGS': ' '.join(link_args)} 4746endif 4747summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4748if 'cpp' in all_languages 4749 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4750endif 4751if 'objc' in all_languages 4752 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4753endif 4754summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4755summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4756summary_info += {'PIE': get_option('b_pie')} 4757summary_info += {'static build': get_option('prefer_static')} 4758summary_info += {'malloc trim support': has_malloc_trim} 4759summary_info += {'membarrier': have_membarrier} 4760summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4761summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4762summary_info += {'mutex debugging': get_option('debug_mutex')} 4763summary_info += {'memory allocator': get_option('malloc')} 4764summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4765summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4766summary_info += {'gcov': get_option('b_coverage')} 4767summary_info += {'thread sanitizer': get_option('tsan')} 4768summary_info += {'CFI support': get_option('cfi')} 4769if get_option('cfi') 4770 summary_info += {'CFI debug support': get_option('cfi_debug')} 4771endif 4772summary_info += {'strip binaries': get_option('strip')} 4773summary_info += {'sparse': sparse} 4774summary_info += {'mingw32 support': host_os == 'windows'} 4775summary(summary_info, bool_yn: true, section: 'Compilation') 4776 4777# snarf the cross-compilation information for tests 4778summary_info = {} 4779have_cross = false 4780foreach target: target_dirs 4781 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4782 if fs.exists(tcg_mak) 4783 config_cross_tcg = keyval.load(tcg_mak) 4784 if 'CC' in config_cross_tcg 4785 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4786 have_cross = true 4787 endif 4788 endif 4789endforeach 4790if have_cross 4791 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4792endif 4793 4794# Targets and accelerators 4795summary_info = {} 4796if have_system 4797 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4798 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4799 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4800 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4801 summary_info += {'Xen support': xen.found()} 4802 if xen.found() 4803 summary_info += {'xen ctrl version': xen.version()} 4804 endif 4805 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4806endif 4807summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4808if config_all_accel.has_key('CONFIG_TCG') 4809 if get_option('tcg_interpreter') 4810 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4811 else 4812 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4813 endif 4814 summary_info += {'TCG plugins': get_option('plugins')} 4815 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4816 if have_linux_user or have_bsd_user 4817 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4818 endif 4819endif 4820summary_info += {'target list': ' '.join(target_dirs)} 4821if have_system 4822 summary_info += {'default devices': get_option('default_devices')} 4823 summary_info += {'out of process emulation': multiprocess_allowed} 4824 summary_info += {'vfio-user server': vfio_user_server_allowed} 4825endif 4826summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4827 4828# Block layer 4829summary_info = {} 4830summary_info += {'coroutine backend': coroutine_backend} 4831summary_info += {'coroutine pool': have_coroutine_pool} 4832if have_block 4833 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4834 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4835 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4836 summary_info += {'VirtFS (9P) support': have_virtfs} 4837 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4838 summary_info += {'bochs support': get_option('bochs').allowed()} 4839 summary_info += {'cloop support': get_option('cloop').allowed()} 4840 summary_info += {'dmg support': get_option('dmg').allowed()} 4841 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4842 summary_info += {'vdi support': get_option('vdi').allowed()} 4843 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4844 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4845 summary_info += {'vpc support': get_option('vpc').allowed()} 4846 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4847 summary_info += {'qed support': get_option('qed').allowed()} 4848 summary_info += {'parallels support': get_option('parallels').allowed()} 4849 summary_info += {'FUSE exports': fuse} 4850 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4851endif 4852summary(summary_info, bool_yn: true, section: 'Block layer support') 4853 4854# Crypto 4855summary_info = {} 4856summary_info += {'TLS priority': get_option('tls_priority')} 4857summary_info += {'GNUTLS support': gnutls} 4858if gnutls.found() 4859 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4860endif 4861summary_info += {'libgcrypt': gcrypt} 4862summary_info += {'nettle': nettle} 4863if nettle.found() 4864 summary_info += {' XTS': xts != 'private'} 4865endif 4866summary_info += {'SM4 ALG support': crypto_sm4} 4867summary_info += {'SM3 ALG support': crypto_sm3} 4868summary_info += {'AF_ALG support': have_afalg} 4869summary_info += {'rng-none': get_option('rng_none')} 4870summary_info += {'Linux keyring': have_keyring} 4871summary_info += {'Linux keyutils': keyutils} 4872summary(summary_info, bool_yn: true, section: 'Crypto') 4873 4874# UI 4875summary_info = {} 4876if host_os == 'darwin' 4877 summary_info += {'Cocoa support': cocoa} 4878endif 4879summary_info += {'D-Bus display': dbus_display} 4880summary_info += {'SDL support': sdl} 4881summary_info += {'SDL image support': sdl_image} 4882summary_info += {'GTK support': gtk} 4883summary_info += {'pixman': pixman} 4884summary_info += {'VTE support': vte} 4885summary_info += {'PNG support': png} 4886summary_info += {'VNC support': vnc} 4887if vnc.found() 4888 summary_info += {'VNC SASL support': sasl} 4889 summary_info += {'VNC JPEG support': jpeg} 4890endif 4891summary_info += {'spice protocol support': spice_protocol} 4892if spice_protocol.found() 4893 summary_info += {' spice server support': spice} 4894endif 4895summary_info += {'curses support': curses} 4896summary_info += {'brlapi support': brlapi} 4897summary(summary_info, bool_yn: true, section: 'User interface') 4898 4899# Graphics backends 4900summary_info = {} 4901summary_info += {'VirGL support': virgl} 4902summary_info += {'Rutabaga support': rutabaga} 4903summary(summary_info, bool_yn: true, section: 'Graphics backends') 4904 4905# Audio backends 4906summary_info = {} 4907if host_os not in ['darwin', 'haiku', 'windows'] 4908 summary_info += {'OSS support': oss} 4909 summary_info += {'sndio support': sndio} 4910elif host_os == 'darwin' 4911 summary_info += {'CoreAudio support': coreaudio} 4912elif host_os == 'windows' 4913 summary_info += {'DirectSound support': dsound} 4914endif 4915if host_os == 'linux' 4916 summary_info += {'ALSA support': alsa} 4917 summary_info += {'PulseAudio support': pulse} 4918endif 4919summary_info += {'PipeWire support': pipewire} 4920summary_info += {'JACK support': jack} 4921summary(summary_info, bool_yn: true, section: 'Audio backends') 4922 4923# Network backends 4924summary_info = {} 4925if host_os == 'darwin' 4926 summary_info += {'vmnet.framework support': vmnet} 4927endif 4928summary_info += {'AF_XDP support': libxdp} 4929summary_info += {'slirp support': slirp} 4930summary_info += {'vde support': vde} 4931summary_info += {'netmap support': have_netmap} 4932summary_info += {'l2tpv3 support': have_l2tpv3} 4933summary(summary_info, bool_yn: true, section: 'Network backends') 4934 4935# Libraries 4936summary_info = {} 4937summary_info += {'libtasn1': tasn1} 4938summary_info += {'PAM': pam} 4939summary_info += {'iconv support': iconv} 4940summary_info += {'blkio support': blkio} 4941summary_info += {'curl support': curl} 4942summary_info += {'Multipath support': mpathpersist} 4943summary_info += {'Linux AIO support': libaio} 4944summary_info += {'Linux io_uring support': linux_io_uring} 4945summary_info += {'ATTR/XATTR support': libattr} 4946summary_info += {'RDMA support': rdma} 4947summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4948summary_info += {'libcap-ng support': libcap_ng} 4949summary_info += {'bpf support': libbpf} 4950summary_info += {'rbd support': rbd} 4951summary_info += {'smartcard support': cacard} 4952summary_info += {'U2F support': u2f} 4953summary_info += {'libusb': libusb} 4954summary_info += {'usb net redir': usbredir} 4955summary_info += {'OpenGL support (epoxy)': opengl} 4956summary_info += {'GBM': gbm} 4957summary_info += {'libiscsi support': libiscsi} 4958summary_info += {'libnfs support': libnfs} 4959if host_os == 'windows' 4960 if have_ga 4961 summary_info += {'QGA VSS support': have_qga_vss} 4962 endif 4963endif 4964summary_info += {'seccomp support': seccomp} 4965summary_info += {'GlusterFS support': glusterfs} 4966summary_info += {'hv-balloon support': hv_balloon} 4967summary_info += {'TPM support': have_tpm} 4968summary_info += {'libssh support': libssh} 4969summary_info += {'lzo support': lzo} 4970summary_info += {'snappy support': snappy} 4971summary_info += {'bzip2 support': libbzip2} 4972summary_info += {'lzfse support': liblzfse} 4973summary_info += {'zstd support': zstd} 4974summary_info += {'Query Processing Library support': qpl} 4975summary_info += {'UADK Library support': uadk} 4976summary_info += {'qatzip support': qatzip} 4977summary_info += {'NUMA host support': numa} 4978summary_info += {'capstone': capstone} 4979summary_info += {'libpmem support': libpmem} 4980summary_info += {'libdaxctl support': libdaxctl} 4981summary_info += {'libcbor support': libcbor} 4982summary_info += {'libudev': libudev} 4983# Dummy dependency, keep .found() 4984summary_info += {'FUSE lseek': fuse_lseek.found()} 4985summary_info += {'selinux': selinux} 4986summary_info += {'libdw': libdw} 4987if host_os == 'freebsd' 4988 summary_info += {'libinotify-kqueue': inotify} 4989endif 4990if host_os == 'darwin' 4991 summary_info += {'ParavirtualizedGraphics support': pvg} 4992endif 4993summary_info += {'valgrind': valgrind} 4994summary(summary_info, bool_yn: true, section: 'Dependencies') 4995 4996if host_arch == 'unknown' 4997 message() 4998 warning('UNSUPPORTED HOST CPU') 4999 message() 5000 message('Support for CPU host architecture ' + cpu + ' is not currently') 5001 message('maintained. The QEMU project does not guarantee that QEMU will') 5002 message('compile or work on this host CPU. You can help by volunteering') 5003 message('to maintain it and providing a build host for our continuous') 5004 message('integration setup.') 5005 if have_tcg 5006 message() 5007 message('configure has succeeded and you can continue to build, but') 5008 message('QEMU will use a slow interpreter to emulate the target CPU.') 5009 endif 5010elif host_long_bits < 64 5011 message() 5012 warning('DEPRECATED HOST CPU') 5013 message() 5014 message('Support for 32-bit CPU host architecture ' + cpu + ' is going') 5015 message('to be dropped in a future QEMU release.') 5016endif 5017 5018if not supported_oses.contains(host_os) 5019 message() 5020 warning('UNSUPPORTED HOST OS') 5021 message() 5022 message('Support for host OS ' + host_os + 'is not currently maintained.') 5023 message('configure has succeeded and you can continue to build, but') 5024 message('the QEMU project does not guarantee that QEMU will compile or') 5025 message('work on this operating system. You can help by volunteering') 5026 message('to maintain it and providing a build host for our continuous') 5027 message('integration setup. This will ensure that future versions of QEMU') 5028 message('will keep working on ' + host_os + '.') 5029endif 5030 5031if host_arch == 'unknown' or not supported_oses.contains(host_os) 5032 message() 5033 message('If you want to help supporting QEMU on this platform, please') 5034 message('contact the developers at qemu-devel@nongnu.org.') 5035endif 5036 5037actually_reloc = get_option('relocatable') 5038# check if get_relocated_path() is actually able to relocate paths 5039if get_option('relocatable') and \ 5040 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 5041 message() 5042 warning('bindir not included within prefix, the installation will not be relocatable.') 5043 actually_reloc = false 5044endif 5045if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 5046 if host_os == 'windows' 5047 message() 5048 warning('Windows installs should usually be relocatable.') 5049 endif 5050 message() 5051 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 5052 message('Use --disable-relocatable to remove this warning.') 5053endif 5054