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