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