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