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