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