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