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