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