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 if libbpf.found() 2168 libxdp = dependency('libxdp', required: get_option('af_xdp'), 2169 version: '>=1.4.0', method: 'pkg-config') 2170 else 2171 if get_option('af_xdp').enabled() 2172 error('libxdp requested, but libbpf is not available') 2173 endif 2174 endif 2175endif 2176 2177# libdw 2178libdw = not_found 2179if not get_option('libdw').auto() or \ 2180 (not get_option('prefer_static') and (have_system or have_user)) 2181 libdw = dependency('libdw', 2182 method: 'pkg-config', 2183 required: get_option('libdw')) 2184endif 2185 2186################# 2187# config-host.h # 2188################# 2189 2190config_host_data = configuration_data() 2191 2192config_host_data.set('CONFIG_HAVE_RUST', have_rust) 2193audio_drivers_selected = [] 2194if have_system 2195 audio_drivers_available = { 2196 'alsa': alsa.found(), 2197 'coreaudio': coreaudio.found(), 2198 'dsound': dsound.found(), 2199 'jack': jack.found(), 2200 'oss': oss.found(), 2201 'pa': pulse.found(), 2202 'pipewire': pipewire.found(), 2203 'sdl': sdl.found(), 2204 'sndio': sndio.found(), 2205 } 2206 foreach k, v: audio_drivers_available 2207 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v) 2208 endforeach 2209 2210 # Default to native drivers first, OSS second, SDL third 2211 audio_drivers_priority = \ 2212 [ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \ 2213 (host_os == 'linux' ? [] : [ 'sdl' ]) 2214 audio_drivers_default = [] 2215 foreach k: audio_drivers_priority 2216 if audio_drivers_available[k] 2217 audio_drivers_default += k 2218 endif 2219 endforeach 2220 2221 foreach k: get_option('audio_drv_list') 2222 if k == 'default' 2223 audio_drivers_selected += audio_drivers_default 2224 elif not audio_drivers_available[k] 2225 error('Audio driver "@0@" not available.'.format(k)) 2226 else 2227 audio_drivers_selected += k 2228 endif 2229 endforeach 2230endif 2231config_host_data.set('CONFIG_AUDIO_DRIVERS', 2232 '"' + '", "'.join(audio_drivers_selected) + '", ') 2233 2234have_host_block_device = (host_os != 'darwin' or 2235 cc.has_header('IOKit/storage/IOMedia.h')) 2236 2237dbus_display = get_option('dbus_display') \ 2238 .require(gio.version().version_compare('>=2.64'), 2239 error_message: '-display dbus requires glib>=2.64') \ 2240 .require(gdbus_codegen.found(), 2241 error_message: gdbus_codegen_error.format('-display dbus')) \ 2242 .allowed() 2243 2244have_virtfs = get_option('virtfs') \ 2245 .require(host_os == 'linux' or host_os == 'darwin', 2246 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \ 2247 .require(host_os == 'linux' or cc.has_function('pthread_fchdir_np'), 2248 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \ 2249 .require(host_os == 'darwin' or libattr.found(), 2250 error_message: 'virtio-9p (virtfs) on Linux requires libattr-devel') \ 2251 .disable_auto_if(not have_tools and not have_system) \ 2252 .allowed() 2253 2254qga_fsfreeze = false 2255qga_fstrim = false 2256if host_os == 'linux' 2257 if cc.has_header_symbol('linux/fs.h', 'FIFREEZE') 2258 qga_fsfreeze = true 2259 endif 2260 if cc.has_header_symbol('linux/fs.h', 'FITRIM') 2261 qga_fstrim = true 2262 endif 2263elif host_os == 'freebsd' and cc.has_header_symbol('ufs/ffs/fs.h', 'UFSSUSPEND') 2264 qga_fsfreeze = true 2265endif 2266 2267if get_option('block_drv_ro_whitelist') == '' 2268 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '') 2269else 2270 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', 2271 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ') 2272endif 2273if get_option('block_drv_rw_whitelist') == '' 2274 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '') 2275else 2276 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', 2277 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ') 2278endif 2279 2280foreach k : get_option('trace_backends') 2281 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true) 2282endforeach 2283config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file')) 2284config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority')) 2285if iasl.found() 2286 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path()) 2287endif 2288config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) 2289config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) 2290config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) 2291config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir) 2292config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir) 2293 2294qemu_firmwarepath = '' 2295foreach k : get_option('qemu_firmwarepath') 2296 qemu_firmwarepath += '"' + get_option('prefix') / k + '", ' 2297endforeach 2298config_host_data.set('CONFIG_QEMU_FIRMWAREPATH', qemu_firmwarepath) 2299 2300config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir')) 2301config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir) 2302config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir')) 2303config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir')) 2304config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) 2305config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) 2306 2307if enable_modules 2308 config_host_data.set('CONFIG_STAMP', run_command( 2309 meson.current_source_dir() / 'scripts/qemu-stamp.py', 2310 meson.project_version(), get_option('pkgversion'), '--', 2311 meson.current_source_dir() / 'configure', 2312 capture: true, check: true).stdout().strip()) 2313endif 2314 2315have_slirp_smbd = get_option('slirp_smbd') \ 2316 .require(host_os != 'windows', error_message: 'Host smbd not supported on this platform.') \ 2317 .allowed() 2318if have_slirp_smbd 2319 smbd_path = get_option('smbd') 2320 if smbd_path == '' 2321 smbd_path = (host_os == 'sunos' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd') 2322 endif 2323 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path) 2324endif 2325 2326config_host_data.set('HOST_' + host_arch.to_upper(), 1) 2327 2328kvm_targets_c = '""' 2329if get_option('kvm').allowed() and host_os == 'linux' 2330 kvm_targets_c = '"' + '" ,"'.join(kvm_targets) + '"' 2331endif 2332config_host_data.set('CONFIG_KVM_TARGETS', kvm_targets_c) 2333 2334if get_option('module_upgrades') and not enable_modules 2335 error('Cannot enable module-upgrades as modules are not enabled') 2336endif 2337config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades')) 2338 2339config_host_data.set('CONFIG_ATTR', libattr.found()) 2340config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools')) 2341config_host_data.set('CONFIG_BRLAPI', brlapi.found()) 2342config_host_data.set('CONFIG_BSD', host_os in bsd_oses) 2343config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd') 2344config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2345config_host_data.set('CONFIG_COCOA', cocoa.found()) 2346config_host_data.set('CONFIG_DARWIN', host_os == 'darwin') 2347config_host_data.set('CONFIG_FDT', fdt.found()) 2348config_host_data.set('CONFIG_FUZZ', get_option('fuzzing')) 2349config_host_data.set('CONFIG_GCOV', get_option('b_coverage')) 2350config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 2351config_host_data.set('CONFIG_LINUX', host_os == 'linux') 2352config_host_data.set('CONFIG_POSIX', host_os != 'windows') 2353config_host_data.set('CONFIG_WIN32', host_os == 'windows') 2354config_host_data.set('CONFIG_LZO', lzo.found()) 2355config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 2356config_host_data.set('CONFIG_BLKIO', blkio.found()) 2357if blkio.found() 2358 config_host_data.set('CONFIG_BLKIO_VHOST_VDPA_FD', 2359 blkio.version().version_compare('>=1.3.0')) 2360 config_host_data.set('CONFIG_BLKIO_WRITE_ZEROS_FUA', 2361 blkio.version().version_compare('>=1.4.0')) 2362endif 2363config_host_data.set('CONFIG_CURL', curl.found()) 2364config_host_data.set('CONFIG_CURSES', curses.found()) 2365config_host_data.set('CONFIG_GBM', gbm.found()) 2366config_host_data.set('CONFIG_GIO', gio.found()) 2367config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 2368if glusterfs.found() 2369 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4')) 2370 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5')) 2371 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6')) 2372 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6')) 2373 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat) 2374 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat) 2375endif 2376config_host_data.set('CONFIG_GTK', gtk.found()) 2377config_host_data.set('CONFIG_VTE', vte.found()) 2378config_host_data.set('CONFIG_GTK_CLIPBOARD', have_gtk_clipboard) 2379config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser')) 2380config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 2381config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 2382config_host_data.set('CONFIG_EBPF', libbpf.found()) 2383config_host_data.set('CONFIG_AF_XDP', libxdp.found()) 2384config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 2385config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 2386config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 2387config_host_data.set('CONFIG_LIBSSH', libssh.found()) 2388config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 2389config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 2390config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 2391config_host_data.set('CONFIG_MODULES', enable_modules) 2392config_host_data.set('CONFIG_NUMA', numa.found()) 2393if numa.found() 2394 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY', 2395 cc.has_function('numa_has_preferred_many', 2396 dependencies: numa)) 2397endif 2398config_host_data.set('CONFIG_OPENGL', opengl.found()) 2399config_host_data.set('CONFIG_PLUGIN', get_option('plugins')) 2400config_host_data.set('CONFIG_RBD', rbd.found()) 2401config_host_data.set('CONFIG_RDMA', rdma.found()) 2402config_host_data.set('CONFIG_RELOCATABLE', get_option('relocatable')) 2403config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack')) 2404config_host_data.set('CONFIG_SDL', sdl.found()) 2405config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 2406config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 2407if seccomp.found() 2408 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) 2409endif 2410config_host_data.set('CONFIG_PIXMAN', pixman.found()) 2411config_host_data.set('CONFIG_SLIRP', slirp.found()) 2412config_host_data.set('CONFIG_SNAPPY', snappy.found()) 2413config_host_data.set('CONFIG_SOLARIS', host_os == 'sunos') 2414if get_option('tcg').allowed() 2415 config_host_data.set('CONFIG_TCG', 1) 2416 config_host_data.set('CONFIG_TCG_INTERPRETER', tcg_arch == 'tci') 2417endif 2418config_host_data.set('CONFIG_TPM', have_tpm) 2419config_host_data.set('CONFIG_TSAN', get_option('tsan')) 2420config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 2421config_host_data.set('CONFIG_VDE', vde.found()) 2422config_host_data.set('CONFIG_VHOST', have_vhost) 2423config_host_data.set('CONFIG_VHOST_NET', have_vhost_net) 2424config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user) 2425config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa) 2426config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel) 2427config_host_data.set('CONFIG_VHOST_USER', have_vhost_user) 2428config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto) 2429config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa) 2430config_host_data.set('CONFIG_VMNET', vmnet.found()) 2431config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 2432config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export) 2433config_host_data.set('CONFIG_PNG', png.found()) 2434config_host_data.set('CONFIG_VNC', vnc.found()) 2435config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 2436config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 2437if virgl.found() 2438 config_host_data.set('HAVE_VIRGL_D3D_INFO_EXT', 2439 cc.has_member('struct virgl_renderer_resource_info_ext', 'd3d_tex2d', 2440 prefix: '#include <virglrenderer.h>', 2441 dependencies: virgl)) 2442endif 2443config_host_data.set('CONFIG_VIRTFS', have_virtfs) 2444config_host_data.set('CONFIG_VTE', vte.found()) 2445config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 2446config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 2447config_host_data.set('CONFIG_GETTID', has_gettid) 2448config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 2449config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 2450config_host_data.set('CONFIG_TASN1', tasn1.found()) 2451config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 2452config_host_data.set('CONFIG_NETTLE', nettle.found()) 2453config_host_data.set('CONFIG_CRYPTO_SM4', crypto_sm4.found()) 2454config_host_data.set('CONFIG_HOGWEED', hogweed.found()) 2455config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 2456config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 2457config_host_data.set('CONFIG_STATX', has_statx) 2458config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 2459config_host_data.set('CONFIG_ZSTD', zstd.found()) 2460config_host_data.set('CONFIG_QPL', qpl.found()) 2461config_host_data.set('CONFIG_UADK', uadk.found()) 2462config_host_data.set('CONFIG_QATZIP', qatzip.found()) 2463config_host_data.set('CONFIG_FUSE', fuse.found()) 2464config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 2465config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 2466if spice_protocol.found() 2467config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 2468config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 2469config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 2470endif 2471config_host_data.set('CONFIG_SPICE', spice.found()) 2472config_host_data.set('CONFIG_X11', x11.found()) 2473config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 2474config_host_data.set('CONFIG_CFI', get_option('cfi')) 2475config_host_data.set('CONFIG_SELINUX', selinux.found()) 2476config_host_data.set('CONFIG_XEN_BACKEND', xen.found()) 2477config_host_data.set('CONFIG_LIBDW', libdw.found()) 2478if xen.found() 2479 # protect from xen.version() having less than three components 2480 xen_version = xen.version().split('.') + ['0', '0'] 2481 xen_ctrl_version = xen_version[0] + \ 2482 ('0' + xen_version[1]).substring(-2) + \ 2483 ('0' + xen_version[2]).substring(-2) 2484 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version) 2485endif 2486config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 2487config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 2488config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 2489config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 2490 2491config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 2492config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 2493 2494have_coroutine_pool = get_option('coroutine_pool') 2495if get_option('debug_stack_usage') and have_coroutine_pool 2496 message('Disabling coroutine pool to measure stack usage') 2497 have_coroutine_pool = false 2498endif 2499config_host_data.set('CONFIG_COROUTINE_POOL', have_coroutine_pool) 2500config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock')) 2501config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 2502config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 2503config_host_data.set('CONFIG_DEBUG_TCG', get_option('debug_tcg')) 2504config_host_data.set('CONFIG_DEBUG_REMAP', get_option('debug_remap')) 2505config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 2506config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) 2507config_host_data.set('CONFIG_FSFREEZE', qga_fsfreeze) 2508config_host_data.set('CONFIG_FSTRIM', qga_fstrim) 2509 2510# has_header 2511config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 2512config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 2513config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 2514config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 2515config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 2516config_host_data.set('HAVE_OPENAT2_H', cc.has_header('linux/openat2.h')) 2517config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 2518config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 2519config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 2520config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 2521if host_os == 'windows' 2522 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h')) 2523endif 2524 2525# has_function 2526config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range')) 2527config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 2528config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 2529config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 2530config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 2531config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 2532config_host_data.set('CONFIG_GETCPU', cc.has_function('getcpu', prefix: gnu_source_prefix)) 2533config_host_data.set('CONFIG_SCHED_GETCPU', cc.has_function('sched_getcpu', prefix: '#include <sched.h>')) 2534# Note that we need to specify prefix: here to avoid incorrectly 2535# thinking that Windows has posix_memalign() 2536config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 2537config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 2538config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 2539config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 2540config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 2541config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 2542config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 2543config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 2544config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 2545config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 2546config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 2547config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 2548config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 2549config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) 2550config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice) 2551config_host_data.set('HAVE_GLIB_WITH_ALIGNED_ALLOC', glib_has_aligned_alloc) 2552config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 2553config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 2554config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 2555if rbd.found() 2556 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS', 2557 cc.has_function('rbd_namespace_exists', 2558 dependencies: rbd, 2559 prefix: '#include <rbd/librbd.h>')) 2560endif 2561if rdma.found() 2562 config_host_data.set('HAVE_IBV_ADVISE_MR', 2563 cc.has_function('ibv_advise_mr', 2564 dependencies: rdma, 2565 prefix: '#include <infiniband/verbs.h>')) 2566endif 2567 2568have_asan_fiber = false 2569if get_option('asan') and \ 2570 not cc.has_function('__sanitizer_start_switch_fiber', 2571 args: '-fsanitize=address', 2572 prefix: '#include <sanitizer/asan_interface.h>') 2573 warning('Missing ASAN due to missing fiber annotation interface') 2574 warning('Without code annotation, the report may be inferior.') 2575else 2576 have_asan_fiber = true 2577endif 2578config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber) 2579 2580have_inotify_init = cc.has_header_symbol('sys/inotify.h', 'inotify_init') 2581have_inotify_init1 = cc.has_header_symbol('sys/inotify.h', 'inotify_init1') 2582inotify = not_found 2583if (have_inotify_init or have_inotify_init1) and host_os == 'freebsd' 2584 # libinotify-kqueue 2585 inotify = cc.find_library('inotify') 2586 if have_inotify_init 2587 have_inotify_init = inotify.found() 2588 endif 2589 if have_inotify_init1 2590 have_inotify_init1 = inotify.found() 2591 endif 2592endif 2593config_host_data.set('CONFIG_INOTIFY', have_inotify_init) 2594config_host_data.set('CONFIG_INOTIFY1', have_inotify_init1) 2595 2596# has_header_symbol 2597config_host_data.set('CONFIG_BLKZONED', 2598 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE')) 2599config_host_data.set('CONFIG_EPOLL_CREATE1', 2600 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 2601config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 2602 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 2603 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 2604config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 2605 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 2606config_host_data.set('CONFIG_FIEMAP', 2607 cc.has_header('linux/fiemap.h') and 2608 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 2609config_host_data.set('CONFIG_GETRANDOM', 2610 cc.has_function('getrandom') and 2611 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 2612config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 2613 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 2614config_host_data.set('CONFIG_RTNETLINK', 2615 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 2616config_host_data.set('CONFIG_SYSMACROS', 2617 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 2618config_host_data.set('HAVE_OPTRESET', 2619 cc.has_header_symbol('getopt.h', 'optreset')) 2620config_host_data.set('HAVE_IPPROTO_MPTCP', 2621 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 2622 2623# has_member 2624config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 2625 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 2626 prefix: '#include <signal.h>')) 2627config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 2628 cc.has_member('struct stat', 'st_atim', 2629 prefix: '#include <sys/stat.h>')) 2630config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY', 2631 cc.has_member('struct blk_zone', 'capacity', 2632 prefix: '#include <linux/blkzoned.h>')) 2633 2634# has_type 2635config_host_data.set('CONFIG_IOVEC', 2636 cc.has_type('struct iovec', 2637 prefix: '#include <sys/uio.h>')) 2638config_host_data.set('HAVE_UTMPX', 2639 cc.has_type('struct utmpx', 2640 prefix: '#include <utmpx.h>')) 2641 2642config_host_data.set('CONFIG_EVENTFD', cc.links(''' 2643 #include <sys/eventfd.h> 2644 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 2645config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 2646 #include <unistd.h> 2647 int main(void) { 2648 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 2649 return fdatasync(0); 2650 #else 2651 #error Not supported 2652 #endif 2653 }''')) 2654 2655has_madvise = cc.links(gnu_source_prefix + ''' 2656 #include <sys/types.h> 2657 #include <sys/mman.h> 2658 #include <stddef.h> 2659 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 2660missing_madvise_proto = false 2661if has_madvise 2662 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 2663 # but forget to prototype it. In this case, has_madvise will be true (the 2664 # test program links despite a compile warning). To detect the 2665 # missing-prototype case, we try again with a definitely-bogus prototype. 2666 # This will only compile if the system headers don't provide the prototype; 2667 # otherwise the conflicting prototypes will cause a compiler error. 2668 missing_madvise_proto = cc.links(gnu_source_prefix + ''' 2669 #include <sys/types.h> 2670 #include <sys/mman.h> 2671 #include <stddef.h> 2672 extern int madvise(int); 2673 int main(void) { return madvise(0); }''') 2674endif 2675config_host_data.set('CONFIG_MADVISE', has_madvise) 2676config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 2677 2678config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 2679 #include <sys/mman.h> 2680 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 2681config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 2682 #include <fcntl.h> 2683 #if !defined(AT_EMPTY_PATH) 2684 # error missing definition 2685 #else 2686 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 2687 #endif''')) 2688 2689# On Darwin posix_madvise() has the same return semantics as plain madvise(), 2690# i.e. errno is set and -1 is returned. That's not really how POSIX defines the 2691# function. On the flip side, it has madvise() which is preferred anyways. 2692if host_os != 'darwin' 2693 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 2694 #include <sys/mman.h> 2695 #include <stddef.h> 2696 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 2697endif 2698 2699config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 2700 #include <pthread.h> 2701 2702 static void *f(void *p) { return NULL; } 2703 int main(void) 2704 { 2705 pthread_t thread; 2706 pthread_create(&thread, 0, f, 0); 2707 pthread_setname_np(thread, "QEMU"); 2708 return 0; 2709 }''', dependencies: threads)) 2710config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 2711 #include <pthread.h> 2712 2713 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 2714 int main(void) 2715 { 2716 pthread_t thread; 2717 pthread_create(&thread, 0, f, 0); 2718 return 0; 2719 }''', dependencies: threads)) 2720config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + ''' 2721 #include <pthread.h> 2722 #include <pthread_np.h> 2723 2724 static void *f(void *p) { return NULL; } 2725 int main(void) 2726 { 2727 pthread_t thread; 2728 pthread_create(&thread, 0, f, 0); 2729 pthread_set_name_np(thread, "QEMU"); 2730 return 0; 2731 }''', dependencies: threads)) 2732config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + ''' 2733 #include <pthread.h> 2734 #include <time.h> 2735 2736 int main(void) 2737 { 2738 pthread_condattr_t attr 2739 pthread_condattr_init(&attr); 2740 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 2741 return 0; 2742 }''', dependencies: threads)) 2743config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + ''' 2744 #include <pthread.h> 2745 2746 static void *f(void *p) { return NULL; } 2747 int main(void) 2748 { 2749 int setsize = CPU_ALLOC_SIZE(64); 2750 pthread_t thread; 2751 cpu_set_t *cpuset; 2752 pthread_create(&thread, 0, f, 0); 2753 cpuset = CPU_ALLOC(64); 2754 CPU_ZERO_S(setsize, cpuset); 2755 pthread_setaffinity_np(thread, setsize, cpuset); 2756 pthread_getaffinity_np(thread, setsize, cpuset); 2757 CPU_FREE(cpuset); 2758 return 0; 2759 }''', dependencies: threads)) 2760config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 2761 #include <sys/signalfd.h> 2762 #include <stddef.h> 2763 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 2764config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 2765 #include <unistd.h> 2766 #include <fcntl.h> 2767 #include <limits.h> 2768 2769 int main(void) 2770 { 2771 int len, fd = 0; 2772 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 2773 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 2774 return 0; 2775 }''')) 2776 2777config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 2778 #include <sys/mman.h> 2779 int main(void) { 2780 return mlockall(MCL_FUTURE); 2781 }''')) 2782 2783have_l2tpv3 = false 2784if get_option('l2tpv3').allowed() and have_system 2785 have_l2tpv3 = cc.has_type('struct mmsghdr', 2786 prefix: gnu_source_prefix + ''' 2787 #include <sys/socket.h> 2788 #include <linux/ip.h>''') 2789endif 2790config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2791 2792have_netmap = false 2793if get_option('netmap').allowed() and have_system 2794 have_netmap = cc.compiles(''' 2795 #include <inttypes.h> 2796 #include <net/if.h> 2797 #include <net/netmap.h> 2798 #include <net/netmap_user.h> 2799 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2800 #error 2801 #endif 2802 int main(void) { return 0; }''') 2803 if not have_netmap and get_option('netmap').enabled() 2804 error('Netmap headers not available') 2805 endif 2806endif 2807config_host_data.set('CONFIG_NETMAP', have_netmap) 2808 2809# Work around a system header bug with some kernel/XFS header 2810# versions where they both try to define 'struct fsxattr': 2811# xfs headers will not try to redefine structs from linux headers 2812# if this macro is set. 2813config_host_data.set('HAVE_FSXATTR', cc.links(''' 2814 #include <linux/fs.h> 2815 struct fsxattr foo; 2816 int main(void) { 2817 return 0; 2818 }''')) 2819 2820# Some versions of Mac OS X incorrectly define SIZE_MAX 2821config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2822 #include <stdint.h> 2823 #include <stdio.h> 2824 int main(void) { 2825 return printf("%zu", SIZE_MAX); 2826 }''', args: ['-Werror'])) 2827 2828# See if 64-bit atomic operations are supported. 2829# Note that without __atomic builtins, we can only 2830# assume atomic loads/stores max at pointer size. 2831config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 2832 #include <stdint.h> 2833 int main(void) 2834 { 2835 uint64_t x = 0, y = 0; 2836 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 2837 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 2838 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2839 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 2840 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 2841 return 0; 2842 }''', args: qemu_isa_flags)) 2843 2844has_int128_type = cc.compiles(''' 2845 __int128_t a; 2846 __uint128_t b; 2847 int main(void) { b = a; }''') 2848config_host_data.set('CONFIG_INT128_TYPE', has_int128_type) 2849 2850has_int128 = has_int128_type and cc.links(''' 2851 __int128_t a; 2852 __uint128_t b; 2853 int main (void) { 2854 a = a + b; 2855 b = a * b; 2856 a = a * a; 2857 return 0; 2858 }''') 2859config_host_data.set('CONFIG_INT128', has_int128) 2860 2861if has_int128_type 2862 # "do we have 128-bit atomics which are handled inline and specifically not 2863 # via libatomic". The reason we can't use libatomic is documented in the 2864 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 2865 # We only care about these operations on 16-byte aligned pointers, so 2866 # force 16-byte alignment of the pointer, which may be greater than 2867 # __alignof(unsigned __int128) for the host. 2868 atomic_test_128 = ''' 2869 int main(int ac, char **av) { 2870 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16); 2871 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED); 2872 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED); 2873 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2874 return 0; 2875 }''' 2876 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags) 2877 2878 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 2879 2880 if not has_atomic128 2881 # Even with __builtin_assume_aligned, the above test may have failed 2882 # without optimization enabled. Try again with optimizations locally 2883 # enabled for the function. See 2884 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389 2885 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128, 2886 args: qemu_isa_flags) 2887 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt) 2888 2889 if not has_atomic128_opt 2890 config_host_data.set('CONFIG_CMPXCHG128', cc.links(''' 2891 int main(void) 2892 { 2893 __uint128_t x = 0, y = 0; 2894 __sync_val_compare_and_swap_16(&x, y, x); 2895 return 0; 2896 } 2897 ''', args: qemu_isa_flags)) 2898 endif 2899 endif 2900endif 2901 2902config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 2903 #include <sys/auxv.h> 2904 int main(void) { 2905 return getauxval(AT_HWCAP) == 0; 2906 }''')) 2907 2908config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(gnu_source_prefix + ''' 2909 #include <sys/auxv.h> 2910 int main(void) { 2911 unsigned long hwcap = 0; 2912 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); 2913 return hwcap; 2914 }''')) 2915 2916config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 2917 #include <linux/usbdevice_fs.h> 2918 2919 #ifndef USBDEVFS_GET_CAPABILITIES 2920 #error "USBDEVFS_GET_CAPABILITIES undefined" 2921 #endif 2922 2923 #ifndef USBDEVFS_DISCONNECT_CLAIM 2924 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 2925 #endif 2926 2927 int main(void) { return 0; }''')) 2928 2929have_keyring = get_option('keyring') \ 2930 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \ 2931 .require(cc.compiles(''' 2932 #include <errno.h> 2933 #include <asm/unistd.h> 2934 #include <linux/keyctl.h> 2935 #include <sys/syscall.h> 2936 #include <unistd.h> 2937 int main(void) { 2938 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 2939 }'''), error_message: 'keyctl syscall not available on this system').allowed() 2940config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 2941 2942have_cpuid_h = cc.links(''' 2943 #include <cpuid.h> 2944 int main(void) { 2945 unsigned a, b, c, d; 2946 unsigned max = __get_cpuid_max(0, 0); 2947 2948 if (max >= 1) { 2949 __cpuid(1, a, b, c, d); 2950 } 2951 2952 if (max >= 7) { 2953 __cpuid_count(7, 0, a, b, c, d); 2954 } 2955 2956 return 0; 2957 }''') 2958config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 2959 2960# Don't bother to advertise asm/hwprobe.h for old versions that do 2961# not contain RISCV_HWPROBE_EXT_ZBA. 2962config_host_data.set('CONFIG_ASM_HWPROBE_H', 2963 cc.has_header_symbol('asm/hwprobe.h', 2964 'RISCV_HWPROBE_EXT_ZBA')) 2965 2966config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 2967 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 2968 .require(cc.links(''' 2969 #include <cpuid.h> 2970 #include <immintrin.h> 2971 static int __attribute__((target("avx2"))) bar(void *a) { 2972 __m256i x = *(__m256i *)a; 2973 return _mm256_testz_si256(x, x); 2974 } 2975 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 2976 '''), error_message: 'AVX2 not available').allowed()) 2977 2978config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \ 2979 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \ 2980 .require(cc.links(''' 2981 #include <cpuid.h> 2982 #include <immintrin.h> 2983 static int __attribute__((target("avx512bw"))) bar(void *a) { 2984 __m512i *x = a; 2985 __m512i res= _mm512_abs_epi8(*x); 2986 return res[1]; 2987 } 2988 int main(int argc, char *argv[]) { return bar(argv[0]); } 2989 '''), error_message: 'AVX512BW not available').allowed()) 2990 2991# For both AArch64 and AArch32, detect if builtins are available. 2992config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles(''' 2993 #include <arm_neon.h> 2994 #ifndef __ARM_FEATURE_AES 2995 __attribute__((target("+crypto"))) 2996 #endif 2997 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); } 2998 ''')) 2999 3000if get_option('membarrier').disabled() 3001 have_membarrier = false 3002elif host_os == 'windows' 3003 have_membarrier = true 3004elif host_os == 'linux' 3005 have_membarrier = cc.compiles(''' 3006 #include <linux/membarrier.h> 3007 #include <sys/syscall.h> 3008 #include <unistd.h> 3009 #include <stdlib.h> 3010 int main(void) { 3011 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 3012 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 3013 exit(0); 3014 }''') 3015endif 3016config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 3017 .require(have_membarrier, error_message: 'membarrier system call not available') \ 3018 .allowed()) 3019 3020have_afalg = get_option('crypto_afalg') \ 3021 .require(cc.compiles(gnu_source_prefix + ''' 3022 #include <errno.h> 3023 #include <sys/types.h> 3024 #include <sys/socket.h> 3025 #include <linux/if_alg.h> 3026 int main(void) { 3027 int sock; 3028 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 3029 return sock; 3030 } 3031 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 3032config_host_data.set('CONFIG_AF_ALG', have_afalg) 3033 3034config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 3035 'linux/vm_sockets.h', 'AF_VSOCK', 3036 prefix: '#include <sys/socket.h>', 3037)) 3038 3039have_vss = false 3040have_vss_sdk = false # old xp/2003 SDK 3041if host_os == 'windows' and 'cpp' in all_languages 3042 have_vss = cxx.compiles(''' 3043 #define __MIDL_user_allocate_free_DEFINED__ 3044 #include <vss.h> 3045 int main(void) { return VSS_CTX_BACKUP; }''') 3046 have_vss_sdk = cxx.has_header('vscoordint.h') 3047endif 3048config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 3049 3050# Older versions of MinGW do not import _lock_file and _unlock_file properly. 3051# This was fixed for v6.0.0 with commit b48e3ac8969d. 3052if host_os == 'windows' 3053 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 3054 #include <stdio.h> 3055 int main(void) { 3056 _lock_file(NULL); 3057 _unlock_file(NULL); 3058 return 0; 3059 }''', name: '_lock_file and _unlock_file')) 3060endif 3061 3062if host_os == 'windows' 3063 mingw_has_setjmp_longjmp = cc.links(''' 3064 #include <setjmp.h> 3065 int main(void) { 3066 /* 3067 * These functions are not available in setjmp header, but may be 3068 * available at link time, from libmingwex.a. 3069 */ 3070 extern int __mingw_setjmp(jmp_buf); 3071 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int); 3072 jmp_buf env; 3073 __mingw_setjmp(env); 3074 __mingw_longjmp(env, 0); 3075 } 3076 ''', name: 'mingw setjmp and longjmp') 3077 3078 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp 3079 error('mingw must provide setjmp/longjmp for windows-arm64') 3080 endif 3081endif 3082 3083######################## 3084# Target configuration # 3085######################## 3086 3087minikconf = find_program('scripts/minikconf.py') 3088 3089config_all_accel = {} 3090config_all_devices = {} 3091config_devices_mak_list = [] 3092config_devices_h = {} 3093config_target_h = {} 3094config_target_mak = {} 3095 3096disassemblers = { 3097 'alpha' : ['CONFIG_ALPHA_DIS'], 3098 'avr' : ['CONFIG_AVR_DIS'], 3099 'hexagon' : ['CONFIG_HEXAGON_DIS'], 3100 'hppa' : ['CONFIG_HPPA_DIS'], 3101 'i386' : ['CONFIG_I386_DIS'], 3102 'x86_64' : ['CONFIG_I386_DIS'], 3103 'm68k' : ['CONFIG_M68K_DIS'], 3104 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 3105 'mips' : ['CONFIG_MIPS_DIS'], 3106 'or1k' : ['CONFIG_OPENRISC_DIS'], 3107 'ppc' : ['CONFIG_PPC_DIS'], 3108 'riscv' : ['CONFIG_RISCV_DIS'], 3109 'rx' : ['CONFIG_RX_DIS'], 3110 's390' : ['CONFIG_S390_DIS'], 3111 'sh4' : ['CONFIG_SH4_DIS'], 3112 'sparc' : ['CONFIG_SPARC_DIS'], 3113 'xtensa' : ['CONFIG_XTENSA_DIS'], 3114 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 3115} 3116 3117have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 3118host_kconfig = \ 3119 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 3120 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 3121 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ 3122 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 3123 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 3124 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 3125 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 3126 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \ 3127 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 3128 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 3129 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 3130 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 3131 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \ 3132 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 3133 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \ 3134 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \ 3135 (have_rust ? ['CONFIG_HAVE_RUST=y'] : []) 3136 3137ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 3138 3139default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 3140actual_target_dirs = [] 3141fdt_required = [] 3142foreach target : target_dirs 3143 config_target = { 'TARGET_NAME': target.split('-')[0] } 3144 if target.endswith('linux-user') 3145 if host_os != 'linux' 3146 if default_targets 3147 continue 3148 endif 3149 error('Target @0@ is only available on a Linux host'.format(target)) 3150 endif 3151 config_target += { 'CONFIG_LINUX_USER': 'y' } 3152 elif target.endswith('bsd-user') 3153 if host_os not in bsd_oses 3154 if default_targets 3155 continue 3156 endif 3157 error('Target @0@ is only available on a BSD host'.format(target)) 3158 endif 3159 config_target += { 'CONFIG_BSD_USER': 'y' } 3160 elif target.endswith('softmmu') 3161 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' } 3162 config_target += { 'CONFIG_SOFTMMU': 'y' } 3163 endif 3164 if target.endswith('-user') 3165 config_target += { 3166 'CONFIG_USER_ONLY': 'y', 3167 'CONFIG_QEMU_INTERP_PREFIX': 3168 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']) 3169 } 3170 endif 3171 3172 target_kconfig = [] 3173 foreach sym: accelerators 3174 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 3175 config_target += { sym: 'y' } 3176 config_all_accel += { sym: 'y' } 3177 if target in modular_tcg 3178 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 3179 else 3180 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 3181 endif 3182 target_kconfig += [ sym + '=y' ] 3183 endif 3184 endforeach 3185 if target_kconfig.length() == 0 3186 if default_targets 3187 continue 3188 endif 3189 error('No accelerator available for target @0@'.format(target)) 3190 endif 3191 3192 config_target += keyval.load('configs/targets' / target + '.mak') 3193 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 3194 3195 if 'TARGET_NEED_FDT' in config_target and not fdt.found() 3196 if default_targets 3197 warning('Disabling ' + target + ' due to missing libfdt') 3198 else 3199 fdt_required += target 3200 endif 3201 continue 3202 endif 3203 3204 actual_target_dirs += target 3205 3206 # Add default keys 3207 if 'TARGET_BASE_ARCH' not in config_target 3208 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 3209 endif 3210 if 'TARGET_ABI_DIR' not in config_target 3211 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 3212 endif 3213 if 'TARGET_BIG_ENDIAN' not in config_target 3214 config_target += {'TARGET_BIG_ENDIAN': 'n'} 3215 endif 3216 3217 foreach k, v: disassemblers 3218 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 3219 foreach sym: v 3220 config_target += { sym: 'y' } 3221 endforeach 3222 endif 3223 endforeach 3224 3225 config_target_data = configuration_data() 3226 foreach k, v: config_target 3227 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 3228 # do nothing 3229 elif ignored.contains(k) 3230 # do nothing 3231 elif k == 'TARGET_BASE_ARCH' 3232 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 3233 # not used to select files from sourcesets. 3234 config_target_data.set('TARGET_' + v.to_upper(), 1) 3235 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 3236 config_target_data.set_quoted(k, v) 3237 elif v == 'y' 3238 config_target_data.set(k, 1) 3239 elif v == 'n' 3240 config_target_data.set(k, 0) 3241 else 3242 config_target_data.set(k, v) 3243 endif 3244 endforeach 3245 config_target_data.set('QEMU_ARCH', 3246 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 3247 config_target_h += {target: configure_file(output: target + '-config-target.h', 3248 configuration: config_target_data)} 3249 3250 if target.endswith('-softmmu') 3251 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y' 3252 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN'] 3253 3254 config_input = meson.get_external_property(target, 'default') 3255 config_devices_mak = target + '-config-devices.mak' 3256 config_devices_mak = configure_file( 3257 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 3258 output: config_devices_mak, 3259 depfile: config_devices_mak + '.d', 3260 capture: true, 3261 command: [minikconf, 3262 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 3263 config_devices_mak, '@DEPFILE@', '@INPUT@', 3264 host_kconfig, target_kconfig]) 3265 3266 config_devices_data = configuration_data() 3267 config_devices = keyval.load(config_devices_mak) 3268 foreach k, v: config_devices 3269 config_devices_data.set(k, 1) 3270 endforeach 3271 config_devices_mak_list += config_devices_mak 3272 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 3273 configuration: config_devices_data)} 3274 config_target += config_devices 3275 config_all_devices += config_devices 3276 endif 3277 config_target_mak += {target: config_target} 3278endforeach 3279target_dirs = actual_target_dirs 3280 3281target_configs_h = [] 3282foreach target: target_dirs 3283 target_configs_h += config_target_h[target] 3284 target_configs_h += config_devices_h.get(target, []) 3285endforeach 3286genh += custom_target('config-poison.h', 3287 input: [target_configs_h], 3288 output: 'config-poison.h', 3289 capture: true, 3290 command: [find_program('scripts/make-config-poison.sh'), 3291 target_configs_h]) 3292 3293if fdt_required.length() > 0 3294 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3295endif 3296 3297############### 3298# Subprojects # 3299############### 3300 3301libvfio_user_dep = not_found 3302if have_system and vfio_user_server_allowed 3303 libvfio_user_proj = subproject('libvfio-user', required: true) 3304 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3305endif 3306 3307vhost_user = not_found 3308if host_os == 'linux' and have_vhost_user 3309 libvhost_user = subproject('libvhost-user') 3310 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3311endif 3312 3313libvduse = not_found 3314if have_libvduse 3315 libvduse_proj = subproject('libvduse') 3316 libvduse = libvduse_proj.get_variable('libvduse_dep') 3317endif 3318 3319##################### 3320# Generated sources # 3321##################### 3322 3323genh += configure_file(output: 'config-host.h', configuration: config_host_data) 3324 3325hxtool = find_program('scripts/hxtool') 3326shaderinclude = find_program('scripts/shaderinclude.py') 3327qapi_gen = find_program('scripts/qapi-gen.py') 3328qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3329 meson.current_source_dir() / 'scripts/qapi/commands.py', 3330 meson.current_source_dir() / 'scripts/qapi/common.py', 3331 meson.current_source_dir() / 'scripts/qapi/error.py', 3332 meson.current_source_dir() / 'scripts/qapi/events.py', 3333 meson.current_source_dir() / 'scripts/qapi/expr.py', 3334 meson.current_source_dir() / 'scripts/qapi/gen.py', 3335 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3336 meson.current_source_dir() / 'scripts/qapi/main.py', 3337 meson.current_source_dir() / 'scripts/qapi/parser.py', 3338 meson.current_source_dir() / 'scripts/qapi/schema.py', 3339 meson.current_source_dir() / 'scripts/qapi/source.py', 3340 meson.current_source_dir() / 'scripts/qapi/types.py', 3341 meson.current_source_dir() / 'scripts/qapi/visit.py', 3342 meson.current_source_dir() / 'scripts/qapi-gen.py' 3343] 3344 3345tracetool = [ 3346 python, files('scripts/tracetool.py'), 3347 '--backend=' + ','.join(get_option('trace_backends')) 3348] 3349tracetool_depends = files( 3350 'scripts/tracetool/backend/log.py', 3351 'scripts/tracetool/backend/__init__.py', 3352 'scripts/tracetool/backend/dtrace.py', 3353 'scripts/tracetool/backend/ftrace.py', 3354 'scripts/tracetool/backend/simple.py', 3355 'scripts/tracetool/backend/syslog.py', 3356 'scripts/tracetool/backend/ust.py', 3357 'scripts/tracetool/format/ust_events_c.py', 3358 'scripts/tracetool/format/ust_events_h.py', 3359 'scripts/tracetool/format/__init__.py', 3360 'scripts/tracetool/format/d.py', 3361 'scripts/tracetool/format/simpletrace_stap.py', 3362 'scripts/tracetool/format/c.py', 3363 'scripts/tracetool/format/h.py', 3364 'scripts/tracetool/format/log_stap.py', 3365 'scripts/tracetool/format/stap.py', 3366 'scripts/tracetool/__init__.py', 3367) 3368 3369qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3370 meson.current_source_dir(), 3371 get_option('pkgversion'), meson.project_version()] 3372qemu_version = custom_target('qemu-version.h', 3373 output: 'qemu-version.h', 3374 command: qemu_version_cmd, 3375 capture: true, 3376 build_by_default: true, 3377 build_always_stale: true) 3378genh += qemu_version 3379 3380hxdep = [] 3381hx_headers = [ 3382 ['qemu-options.hx', 'qemu-options.def'], 3383 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3384] 3385if have_system 3386 hx_headers += [ 3387 ['hmp-commands.hx', 'hmp-commands.h'], 3388 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3389 ] 3390endif 3391foreach d : hx_headers 3392 hxdep += custom_target(d[1], 3393 input: files(d[0]), 3394 output: d[1], 3395 capture: true, 3396 command: [hxtool, '-h', '@INPUT0@']) 3397endforeach 3398genh += hxdep 3399 3400############### 3401# Trace files # 3402############### 3403 3404# TODO: add each directory to the subdirs from its own meson.build, once 3405# we have those 3406trace_events_subdirs = [ 3407 'crypto', 3408 'qapi', 3409 'qom', 3410 'monitor', 3411 'util', 3412 'gdbstub', 3413] 3414if have_linux_user 3415 trace_events_subdirs += [ 'linux-user' ] 3416endif 3417if have_bsd_user 3418 trace_events_subdirs += [ 'bsd-user' ] 3419endif 3420if have_block 3421 trace_events_subdirs += [ 3422 'authz', 3423 'block', 3424 'chardev', 3425 'io', 3426 'nbd', 3427 'scsi', 3428 ] 3429endif 3430if have_system 3431 trace_events_subdirs += [ 3432 'accel/kvm', 3433 'audio', 3434 'backends', 3435 'backends/tpm', 3436 'ebpf', 3437 'hw/9pfs', 3438 'hw/acpi', 3439 'hw/adc', 3440 'hw/alpha', 3441 'hw/arm', 3442 'hw/audio', 3443 'hw/block', 3444 'hw/char', 3445 'hw/display', 3446 'hw/dma', 3447 'hw/fsi', 3448 'hw/hyperv', 3449 'hw/i2c', 3450 'hw/i386', 3451 'hw/i386/xen', 3452 'hw/i386/kvm', 3453 'hw/ide', 3454 'hw/input', 3455 'hw/intc', 3456 'hw/isa', 3457 'hw/mem', 3458 'hw/mips', 3459 'hw/misc', 3460 'hw/misc/macio', 3461 'hw/net', 3462 'hw/net/can', 3463 'hw/nubus', 3464 'hw/nvme', 3465 'hw/nvram', 3466 'hw/pci', 3467 'hw/pci-host', 3468 'hw/ppc', 3469 'hw/rtc', 3470 'hw/s390x', 3471 'hw/scsi', 3472 'hw/sd', 3473 'hw/sh4', 3474 'hw/sparc', 3475 'hw/sparc64', 3476 'hw/ssi', 3477 'hw/timer', 3478 'hw/tpm', 3479 'hw/ufs', 3480 'hw/usb', 3481 'hw/vfio', 3482 'hw/virtio', 3483 'hw/watchdog', 3484 'hw/xen', 3485 'hw/gpio', 3486 'migration', 3487 'net', 3488 'system', 3489 'ui', 3490 'hw/remote', 3491 ] 3492endif 3493if have_system or have_user 3494 trace_events_subdirs += [ 3495 'accel/tcg', 3496 'hw/core', 3497 'target/arm', 3498 'target/arm/hvf', 3499 'target/hppa', 3500 'target/i386', 3501 'target/i386/kvm', 3502 'target/loongarch', 3503 'target/mips/tcg', 3504 'target/ppc', 3505 'target/riscv', 3506 'target/s390x', 3507 'target/s390x/kvm', 3508 'target/sparc', 3509 ] 3510endif 3511 3512################### 3513# Collect sources # 3514################### 3515 3516authz_ss = ss.source_set() 3517blockdev_ss = ss.source_set() 3518block_ss = ss.source_set() 3519chardev_ss = ss.source_set() 3520common_ss = ss.source_set() 3521crypto_ss = ss.source_set() 3522hwcore_ss = ss.source_set() 3523io_ss = ss.source_set() 3524qmp_ss = ss.source_set() 3525qom_ss = ss.source_set() 3526system_ss = ss.source_set() 3527specific_fuzz_ss = ss.source_set() 3528specific_ss = ss.source_set() 3529rust_devices_ss = ss.source_set() 3530stub_ss = ss.source_set() 3531trace_ss = ss.source_set() 3532user_ss = ss.source_set() 3533util_ss = ss.source_set() 3534 3535# accel modules 3536qtest_module_ss = ss.source_set() 3537tcg_module_ss = ss.source_set() 3538 3539modules = {} 3540target_modules = {} 3541hw_arch = {} 3542target_arch = {} 3543target_system_arch = {} 3544target_user_arch = {} 3545 3546# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3547# that is filled in by qapi/. 3548subdir('qapi') 3549subdir('qobject') 3550subdir('stubs') 3551subdir('trace') 3552subdir('util') 3553subdir('qom') 3554subdir('authz') 3555subdir('crypto') 3556subdir('ui') 3557subdir('gdbstub') 3558if have_system 3559 subdir('hw') 3560else 3561 subdir('hw/core') 3562endif 3563 3564if enable_modules 3565 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3566 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3567endif 3568 3569qom_ss = qom_ss.apply({}) 3570libqom = static_library('qom', qom_ss.sources() + genh, 3571 dependencies: [qom_ss.dependencies()], 3572 build_by_default: false) 3573qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3574 dependencies: qom_ss.dependencies()) 3575 3576event_loop_base = files('event-loop-base.c') 3577event_loop_base = static_library('event-loop-base', 3578 sources: event_loop_base + genh, 3579 build_by_default: false) 3580event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3581 dependencies: [qom]) 3582 3583stub_ss = stub_ss.apply({}) 3584 3585util_ss.add_all(trace_ss) 3586util_ss = util_ss.apply({}) 3587libqemuutil = static_library('qemuutil', 3588 build_by_default: false, 3589 sources: util_ss.sources() + stub_ss.sources() + genh, 3590 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3591qemuutil = declare_dependency(link_with: libqemuutil, 3592 sources: genh + version_res, 3593 dependencies: [event_loop_base]) 3594 3595if have_system or have_user 3596 decodetree = generator(find_program('scripts/decodetree.py'), 3597 output: 'decode-@BASENAME@.c.inc', 3598 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3599 subdir('libdecnumber') 3600 subdir('target') 3601endif 3602 3603subdir('audio') 3604subdir('io') 3605subdir('chardev') 3606subdir('fsdev') 3607subdir('dump') 3608 3609if have_block 3610 block_ss.add(files( 3611 'block.c', 3612 'blockjob.c', 3613 'job.c', 3614 'qemu-io-cmds.c', 3615 )) 3616 if config_host_data.get('CONFIG_REPLICATION') 3617 block_ss.add(files('replication.c')) 3618 endif 3619 3620 subdir('nbd') 3621 subdir('scsi') 3622 subdir('block') 3623 3624 blockdev_ss.add(files( 3625 'blockdev.c', 3626 'blockdev-nbd.c', 3627 'iothread.c', 3628 'job-qmp.c', 3629 )) 3630 3631 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3632 # os-win32.c does not 3633 if host_os == 'windows' 3634 system_ss.add(files('os-win32.c')) 3635 else 3636 blockdev_ss.add(files('os-posix.c')) 3637 endif 3638endif 3639 3640common_ss.add(files('cpu-common.c')) 3641specific_ss.add(files('cpu-target.c')) 3642 3643subdir('system') 3644 3645# Work around a gcc bug/misfeature wherein constant propagation looks 3646# through an alias: 3647# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3648# to guess that a const variable is always zero. Without lto, this is 3649# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3650# without lto, not even the alias is required -- we simply use different 3651# declarations in different compilation units. 3652pagevary = files('page-vary-common.c') 3653if get_option('b_lto') 3654 pagevary_flags = ['-fno-lto'] 3655 if get_option('cfi') 3656 pagevary_flags += '-fno-sanitize=cfi-icall' 3657 endif 3658 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3659 c_args: pagevary_flags) 3660 pagevary = declare_dependency(link_with: pagevary) 3661endif 3662common_ss.add(pagevary) 3663specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3664 3665subdir('backends') 3666subdir('disas') 3667subdir('migration') 3668subdir('monitor') 3669subdir('net') 3670subdir('replay') 3671subdir('semihosting') 3672subdir('stats') 3673subdir('tcg') 3674subdir('fpu') 3675subdir('accel') 3676subdir('plugins') 3677subdir('ebpf') 3678 3679common_user_inc = [] 3680 3681subdir('common-user') 3682subdir('bsd-user') 3683subdir('linux-user') 3684 3685# needed for fuzzing binaries 3686subdir('tests/qtest/libqos') 3687subdir('tests/qtest/fuzz') 3688 3689# accel modules 3690tcg_real_module_ss = ss.source_set() 3691tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3692specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3693target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3694 'tcg': tcg_real_module_ss }} 3695 3696############################################## 3697# Internal static_libraries and dependencies # 3698############################################## 3699 3700modinfo_collect = find_program('scripts/modinfo-collect.py') 3701modinfo_generate = find_program('scripts/modinfo-generate.py') 3702modinfo_files = [] 3703 3704block_mods = [] 3705system_mods = [] 3706emulator_modules = [] 3707foreach d, list : modules 3708 if not (d == 'block' ? have_block : have_system) 3709 continue 3710 endif 3711 3712 foreach m, module_ss : list 3713 if enable_modules 3714 module_ss.add(modulecommon) 3715 module_ss = module_ss.apply(config_all_devices, strict: false) 3716 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3717 dependencies: module_ss.dependencies(), pic: true) 3718 if d == 'block' 3719 block_mods += sl 3720 else 3721 system_mods += sl 3722 endif 3723 emulator_modules += shared_module(sl.name(), 3724 name_prefix: '', 3725 objects: sl.extract_all_objects(recursive: false), 3726 dependencies: module_ss.dependencies(), 3727 install: true, 3728 install_dir: qemu_moddir) 3729 if module_ss.sources() != [] 3730 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3731 # input. Sources can be used multiple times but objects are 3732 # unique when it comes to lookup in compile_commands.json. 3733 # Depnds on a mesion version with 3734 # https://github.com/mesonbuild/meson/pull/8900 3735 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3736 output: d + '-' + m + '.modinfo', 3737 input: module_ss.sources() + genh, 3738 capture: true, 3739 command: [modinfo_collect, module_ss.sources()]) 3740 endif 3741 else 3742 if d == 'block' 3743 block_ss.add_all(module_ss) 3744 else 3745 system_ss.add_all(module_ss) 3746 endif 3747 endif 3748 endforeach 3749endforeach 3750 3751foreach d, list : target_modules 3752 foreach m, module_ss : list 3753 if enable_modules 3754 module_ss.add(modulecommon) 3755 foreach target : target_dirs 3756 if target.endswith('-softmmu') 3757 config_target = config_target_mak[target] 3758 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3759 c_args = ['-DCOMPILING_PER_TARGET', 3760 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3761 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3762 target_module_ss = module_ss.apply(config_target, strict: false) 3763 if target_module_ss.sources() != [] 3764 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3765 sl = static_library(module_name, 3766 [genh, target_module_ss.sources()], 3767 dependencies: target_module_ss.dependencies(), 3768 include_directories: target_inc, 3769 c_args: c_args, 3770 pic: true) 3771 system_mods += sl 3772 emulator_modules += shared_module(sl.name(), 3773 name_prefix: '', 3774 objects: sl.extract_all_objects(recursive: false), 3775 dependencies: target_module_ss.dependencies(), 3776 install: true, 3777 install_dir: qemu_moddir) 3778 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3779 modinfo_files += custom_target(module_name + '.modinfo', 3780 output: module_name + '.modinfo', 3781 input: target_module_ss.sources() + genh, 3782 capture: true, 3783 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3784 endif 3785 endif 3786 endforeach 3787 else 3788 specific_ss.add_all(module_ss) 3789 endif 3790 endforeach 3791endforeach 3792 3793if enable_modules 3794 foreach target : target_dirs 3795 if target.endswith('-softmmu') 3796 config_target = config_target_mak[target] 3797 config_devices_mak = target + '-config-devices.mak' 3798 modinfo_src = custom_target('modinfo-' + target + '.c', 3799 output: 'modinfo-' + target + '.c', 3800 input: modinfo_files, 3801 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3802 capture: true) 3803 3804 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3805 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3806 3807 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3808 hw_arch[arch].add(modinfo_dep) 3809 endif 3810 endforeach 3811 3812 if emulator_modules.length() > 0 3813 alias_target('modules', emulator_modules) 3814 endif 3815endif 3816 3817nm = find_program('nm') 3818undefsym = find_program('scripts/undefsym.py') 3819block_syms = custom_target('block.syms', output: 'block.syms', 3820 input: [libqemuutil, block_mods], 3821 capture: true, 3822 command: [undefsym, nm, '@INPUT@']) 3823qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3824 input: [libqemuutil, system_mods], 3825 capture: true, 3826 command: [undefsym, nm, '@INPUT@']) 3827 3828authz_ss = authz_ss.apply({}) 3829libauthz = static_library('authz', authz_ss.sources() + genh, 3830 dependencies: [authz_ss.dependencies()], 3831 build_by_default: false) 3832 3833authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3834 dependencies: [authz_ss.dependencies(), qom]) 3835 3836crypto_ss = crypto_ss.apply({}) 3837libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3838 dependencies: [crypto_ss.dependencies()], 3839 build_by_default: false) 3840 3841crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3842 dependencies: [crypto_ss.dependencies(), authz, qom]) 3843 3844io_ss = io_ss.apply({}) 3845libio = static_library('io', io_ss.sources() + genh, 3846 dependencies: [io_ss.dependencies()], 3847 link_with: libqemuutil, 3848 build_by_default: false) 3849 3850io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3851 dependencies: [io_ss.dependencies(), crypto, qom]) 3852 3853libmigration = static_library('migration', sources: migration_files + genh, 3854 build_by_default: false) 3855migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3856 dependencies: [qom, io]) 3857system_ss.add(migration) 3858 3859block_ss = block_ss.apply({}) 3860libblock = static_library('block', block_ss.sources() + genh, 3861 dependencies: block_ss.dependencies(), 3862 build_by_default: false) 3863 3864block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3865 dependencies: [block_ss.dependencies(), crypto, io]) 3866 3867blockdev_ss = blockdev_ss.apply({}) 3868libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3869 dependencies: blockdev_ss.dependencies(), 3870 build_by_default: false) 3871 3872blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3873 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3874 3875qmp_ss = qmp_ss.apply({}) 3876libqmp = static_library('qmp', qmp_ss.sources() + genh, 3877 dependencies: qmp_ss.dependencies(), 3878 build_by_default: false) 3879 3880qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3881 dependencies: qmp_ss.dependencies()) 3882 3883libchardev = static_library('chardev', chardev_ss.sources() + genh, 3884 dependencies: chardev_ss.dependencies(), 3885 build_by_default: false) 3886 3887chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 3888 dependencies: chardev_ss.dependencies()) 3889 3890hwcore_ss = hwcore_ss.apply({}) 3891libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3892 build_by_default: false) 3893hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 3894common_ss.add(hwcore) 3895 3896########### 3897# Targets # 3898########### 3899 3900system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3901common_ss.add(qom, qemuutil) 3902 3903common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 3904common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3905 3906# Note that this library is never used directly (only through extract_objects) 3907# and is not built by default; therefore, source files not used by the build 3908# configuration will be in build.ninja, but are never built by default. 3909common_all = static_library('common', 3910 build_by_default: false, 3911 sources: common_ss.all_sources() + genh, 3912 include_directories: common_user_inc, 3913 implicit_include_directories: false, 3914 dependencies: common_ss.all_dependencies()) 3915 3916if have_rust and have_system 3917 rustc_args = run_command( 3918 find_program('scripts/rust/rustc_args.py'), 3919 '--config-headers', meson.project_build_root() / 'config-host.h', 3920 capture : true, 3921 check: true).stdout().strip().split() 3922 rustc_args += ['-D', 'unsafe_op_in_unsafe_fn'] 3923 bindgen_args = [ 3924 '--disable-header-comment', 3925 '--raw-line', '// @generated', 3926 '--ctypes-prefix', 'core::ffi', 3927 '--formatter', 'rustfmt', 3928 '--generate-block', 3929 '--generate-cstr', 3930 '--impl-debug', 3931 '--merge-extern-blocks', 3932 '--no-doc-comments', 3933 '--use-core', 3934 '--with-derive-default', 3935 '--no-size_t-is-usize', 3936 '--no-layout-tests', 3937 '--no-prepend-enum-name', 3938 '--allowlist-file', meson.project_source_root() + '/include/.*', 3939 '--allowlist-file', meson.project_source_root() + '/.*', 3940 '--allowlist-file', meson.project_build_root() + '/.*' 3941 ] 3942 c_enums = [ 3943 'DeviceCategory', 3944 'GpioPolarity', 3945 'MachineInitPhase', 3946 'MemoryDeviceInfoKind', 3947 'MigrationPolicy', 3948 'MigrationPriority', 3949 'QEMUChrEvent', 3950 'QEMUClockType', 3951 'device_endian', 3952 'module_init_type', 3953 ] 3954 foreach enum : c_enums 3955 bindgen_args += ['--rustified-enum', enum] 3956 endforeach 3957 c_bitfields = [ 3958 'ClockEvent', 3959 'VMStateFlags', 3960 ] 3961 foreach enum : c_bitfields 3962 bindgen_args += ['--bitfield-enum', enum] 3963 endforeach 3964 3965 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 3966 # 3967 # Rust bindings generation with `bindgen` might fail in some cases where the 3968 # detected `libclang` does not match the expected `clang` version/target. In 3969 # this case you must pass the path to `clang` and `libclang` to your build 3970 # command invocation using the environment variables CLANG_PATH and 3971 # LIBCLANG_PATH 3972 bindings_rs = import('rust').bindgen( 3973 input: 'rust/wrapper.h', 3974 dependencies: common_ss.all_dependencies(), 3975 output: 'bindings.rs', 3976 include_directories: include_directories('.', 'include'), 3977 bindgen_version: ['>=0.69.4'], 3978 args: bindgen_args, 3979 ) 3980 subdir('rust') 3981endif 3982 3983 3984feature_to_c = find_program('scripts/feature_to_c.py') 3985 3986if host_os == 'darwin' 3987 entitlement = find_program('scripts/entitlement.sh') 3988endif 3989 3990traceable = [] 3991emulators = {} 3992foreach target : target_dirs 3993 config_target = config_target_mak[target] 3994 target_name = config_target['TARGET_NAME'] 3995 target_base_arch = config_target['TARGET_BASE_ARCH'] 3996 arch_srcs = [config_target_h[target]] 3997 arch_deps = [] 3998 c_args = ['-DCOMPILING_PER_TARGET', 3999 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4000 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4001 link_args = emulator_link_args 4002 4003 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4004 if host_os == 'linux' 4005 target_inc += include_directories('linux-headers', is_system: true) 4006 endif 4007 if target.endswith('-softmmu') 4008 target_type='system' 4009 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4010 arch_srcs += t.sources() 4011 arch_deps += t.dependencies() 4012 4013 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4014 if hw_arch.has_key(hw_dir) 4015 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4016 arch_srcs += hw.sources() 4017 arch_deps += hw.dependencies() 4018 endif 4019 4020 arch_srcs += config_devices_h[target] 4021 link_args += ['@block.syms', '@qemu.syms'] 4022 else 4023 abi = config_target['TARGET_ABI_DIR'] 4024 target_type='user' 4025 target_inc += common_user_inc 4026 if target_base_arch in target_user_arch 4027 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4028 arch_srcs += t.sources() 4029 arch_deps += t.dependencies() 4030 endif 4031 if 'CONFIG_LINUX_USER' in config_target 4032 base_dir = 'linux-user' 4033 endif 4034 if 'CONFIG_BSD_USER' in config_target 4035 base_dir = 'bsd-user' 4036 target_inc += include_directories('bsd-user/' / host_os) 4037 target_inc += include_directories('bsd-user/host/' / host_arch) 4038 dir = base_dir / abi 4039 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4040 endif 4041 target_inc += include_directories( 4042 base_dir, 4043 base_dir / abi, 4044 ) 4045 if 'CONFIG_LINUX_USER' in config_target 4046 dir = base_dir / abi 4047 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4048 if config_target.has_key('TARGET_SYSTBL_ABI') 4049 arch_srcs += \ 4050 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4051 extra_args : config_target['TARGET_SYSTBL_ABI']) 4052 endif 4053 endif 4054 endif 4055 4056 if 'TARGET_XML_FILES' in config_target 4057 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4058 output: target + '-gdbstub-xml.c', 4059 input: files(config_target['TARGET_XML_FILES'].split()), 4060 command: [feature_to_c, '@INPUT@'], 4061 capture: true) 4062 arch_srcs += gdbstub_xml 4063 endif 4064 4065 t = target_arch[target_base_arch].apply(config_target, strict: false) 4066 arch_srcs += t.sources() 4067 arch_deps += t.dependencies() 4068 4069 target_common = common_ss.apply(config_target, strict: false) 4070 objects = common_all.extract_objects(target_common.sources()) 4071 arch_deps += target_common.dependencies() 4072 4073 target_specific = specific_ss.apply(config_target, strict: false) 4074 arch_srcs += target_specific.sources() 4075 arch_deps += target_specific.dependencies() 4076 4077 if have_rust and have_system 4078 target_rust = rust_devices_ss.apply(config_target, strict: false) 4079 crates = [] 4080 foreach dep : target_rust.dependencies() 4081 crates += dep.get_variable('crate') 4082 endforeach 4083 if crates.length() > 0 4084 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4085 output: 'rust_' + target.underscorify() + '.rs', 4086 command: [find_program('scripts/rust/rust_root_crate.sh')] + crates, 4087 capture: true, 4088 build_by_default: true, 4089 build_always_stale: true) 4090 rlib = static_library('rust_' + target.underscorify(), 4091 rlib_rs, 4092 dependencies: target_rust.dependencies(), 4093 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4094 rust_args: rustc_args, 4095 rust_abi: 'c') 4096 arch_deps += declare_dependency(link_whole: [rlib]) 4097 endif 4098 endif 4099 4100 # allow using headers from the dependencies but do not include the sources, 4101 # because this emulator only needs those in "objects". For external 4102 # dependencies, the full dependency is included below in the executable. 4103 lib_deps = [] 4104 foreach dep : arch_deps 4105 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4106 endforeach 4107 4108 lib = static_library('qemu-' + target, 4109 sources: arch_srcs + genh, 4110 dependencies: lib_deps, 4111 objects: objects, 4112 include_directories: target_inc, 4113 c_args: c_args, 4114 build_by_default: false) 4115 4116 if target.endswith('-softmmu') 4117 execs = [{ 4118 'name': 'qemu-system-' + target_name, 4119 'win_subsystem': 'console', 4120 'sources': files('system/main.c'), 4121 'dependencies': [] 4122 }] 4123 if host_os == 'windows' and (sdl.found() or gtk.found()) 4124 execs += [{ 4125 'name': 'qemu-system-' + target_name + 'w', 4126 'win_subsystem': 'windows', 4127 'sources': files('system/main.c'), 4128 'dependencies': [] 4129 }] 4130 endif 4131 if get_option('fuzzing') 4132 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4133 execs += [{ 4134 'name': 'qemu-fuzz-' + target_name, 4135 'win_subsystem': 'console', 4136 'sources': specific_fuzz.sources(), 4137 'dependencies': specific_fuzz.dependencies(), 4138 }] 4139 endif 4140 else 4141 execs = [{ 4142 'name': 'qemu-' + target_name, 4143 'win_subsystem': 'console', 4144 'sources': [], 4145 'dependencies': [] 4146 }] 4147 endif 4148 foreach exe: execs 4149 exe_name = exe['name'] 4150 if host_os == 'darwin' 4151 exe_name += '-unsigned' 4152 endif 4153 4154 emulator = executable(exe_name, exe['sources'], 4155 install: true, 4156 c_args: c_args, 4157 dependencies: arch_deps + exe['dependencies'], 4158 objects: lib.extract_all_objects(recursive: true), 4159 link_depends: [block_syms, qemu_syms], 4160 link_args: link_args, 4161 win_subsystem: exe['win_subsystem']) 4162 4163 if host_os == 'darwin' 4164 icon = 'pc-bios/qemu.rsrc' 4165 build_input = [emulator, files(icon)] 4166 install_input = [ 4167 get_option('bindir') / exe_name, 4168 meson.current_source_dir() / icon 4169 ] 4170 if 'CONFIG_HVF' in config_target 4171 entitlements = 'accel/hvf/entitlements.plist' 4172 build_input += files(entitlements) 4173 install_input += meson.current_source_dir() / entitlements 4174 endif 4175 4176 emulators += {exe['name'] : custom_target(exe['name'], 4177 input: build_input, 4178 output: exe['name'], 4179 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4180 } 4181 4182 meson.add_install_script(entitlement, '--install', 4183 get_option('bindir') / exe['name'], 4184 install_input) 4185 else 4186 emulators += {exe['name']: emulator} 4187 endif 4188 4189 traceable += [{ 4190 'exe': exe['name'], 4191 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4192 }] 4193 4194 endforeach 4195endforeach 4196 4197# Other build targets 4198 4199if get_option('plugins') 4200 install_headers('include/qemu/qemu-plugin.h') 4201 if host_os == 'windows' 4202 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4203 # so that plugin authors can compile against it. 4204 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4205 endif 4206endif 4207 4208subdir('qga') 4209 4210# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4211# when we don't build tools or system 4212if xkbcommon.found() 4213 # used for the update-keymaps target, so include rules even if !have_tools 4214 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4215 dependencies: [qemuutil, xkbcommon], install: have_tools) 4216endif 4217 4218if have_tools 4219 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4220 link_args: '@block.syms', link_depends: block_syms, 4221 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4222 qemu_io = executable('qemu-io', files('qemu-io.c'), 4223 link_args: '@block.syms', link_depends: block_syms, 4224 dependencies: [block, qemuutil], install: true) 4225 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4226 link_args: '@block.syms', link_depends: block_syms, 4227 dependencies: [blockdev, qemuutil, selinux], 4228 install: true) 4229 4230 subdir('storage-daemon') 4231 4232 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4233 traceable += [{ 4234 'exe': exe, 4235 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4236 }] 4237 endforeach 4238 4239 subdir('contrib/elf2dmp') 4240 4241 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4242 dependencies: qemuutil, 4243 install: true) 4244 4245 if have_vhost_user 4246 subdir('contrib/vhost-user-blk') 4247 subdir('contrib/vhost-user-gpu') 4248 subdir('contrib/vhost-user-input') 4249 subdir('contrib/vhost-user-scsi') 4250 endif 4251 4252 if host_os == 'linux' 4253 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4254 dependencies: [qemuutil, libcap_ng], 4255 install: true, 4256 install_dir: get_option('libexecdir')) 4257 4258 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4259 dependencies: [authz, crypto, io, qom, qemuutil, 4260 libcap_ng, mpathpersist], 4261 install: true) 4262 4263 if cpu in ['x86', 'x86_64'] 4264 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4265 dependencies: [authz, crypto, io, qom, qemuutil, 4266 libcap_ng, mpathpersist], 4267 install: true) 4268 endif 4269 endif 4270 4271 if have_ivshmem 4272 subdir('contrib/ivshmem-client') 4273 subdir('contrib/ivshmem-server') 4274 endif 4275endif 4276 4277if stap.found() 4278 foreach t: traceable 4279 foreach stp: [ 4280 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4281 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4282 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4283 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4284 ] 4285 cmd = [ 4286 tracetool, '--group=all', '--format=' + stp['fmt'], 4287 '--binary=' + stp['bin'], 4288 '--probe-prefix=' + t['probe-prefix'], 4289 '@INPUT@', '@OUTPUT@' 4290 ] 4291 4292 custom_target(t['exe'] + stp['ext'], 4293 input: trace_events_all, 4294 output: t['exe'] + stp['ext'], 4295 install: stp['install'], 4296 install_dir: get_option('datadir') / 'systemtap/tapset', 4297 command: cmd, 4298 depend_files: tracetool_depends) 4299 endforeach 4300 endforeach 4301endif 4302 4303subdir('scripts') 4304subdir('tools') 4305subdir('pc-bios') 4306subdir('docs') 4307subdir('tests') 4308if gtk.found() 4309 subdir('po') 4310endif 4311 4312if host_machine.system() == 'windows' 4313 nsis_cmd = [ 4314 find_program('scripts/nsis.py'), 4315 '@OUTPUT@', 4316 get_option('prefix'), 4317 meson.current_source_dir(), 4318 glib_pc.get_variable('bindir'), 4319 host_machine.cpu(), 4320 '--', 4321 '-DDISPLAYVERSION=' + meson.project_version(), 4322 ] 4323 if build_docs 4324 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4325 endif 4326 if gtk.found() 4327 nsis_cmd += '-DCONFIG_GTK=y' 4328 endif 4329 4330 nsis = custom_target('nsis', 4331 output: 'qemu-setup-' + meson.project_version() + '.exe', 4332 input: files('qemu.nsi'), 4333 build_always_stale: true, 4334 command: nsis_cmd + ['@INPUT@']) 4335 alias_target('installer', nsis) 4336endif 4337 4338######################### 4339# Configuration summary # 4340######################### 4341 4342# Build environment 4343summary_info = {} 4344summary_info += {'Build directory': meson.current_build_dir()} 4345summary_info += {'Source path': meson.current_source_dir()} 4346summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4347summary(summary_info, bool_yn: true, section: 'Build environment') 4348 4349# Directories 4350summary_info += {'Install prefix': get_option('prefix')} 4351summary_info += {'BIOS directory': qemu_datadir} 4352pathsep = host_os == 'windows' ? ';' : ':' 4353summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4354summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4355summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4356summary_info += {'module directory': qemu_moddir} 4357summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4358summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4359summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4360if host_os != 'windows' 4361 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4362 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4363else 4364 summary_info += {'local state directory': 'queried at runtime'} 4365endif 4366summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4367summary(summary_info, bool_yn: true, section: 'Directories') 4368 4369# Host binaries 4370summary_info = {} 4371summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4372summary_info += {'sphinx-build': sphinx_build} 4373 4374# FIXME: the [binaries] section of machine files, which can be probed 4375# with find_program(), would be great for passing gdb and genisoimage 4376# paths from configure to Meson. However, there seems to be no way to 4377# hide a program (for example if gdb is too old). 4378if config_host.has_key('GDB') 4379 summary_info += {'gdb': config_host['GDB']} 4380endif 4381summary_info += {'iasl': iasl} 4382summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4383if host_os == 'windows' and have_ga 4384 summary_info += {'wixl': wixl} 4385endif 4386if slirp.found() and have_system 4387 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4388endif 4389summary(summary_info, bool_yn: true, section: 'Host binaries') 4390 4391# Configurable features 4392summary_info = {} 4393summary_info += {'Documentation': build_docs} 4394summary_info += {'system-mode emulation': have_system} 4395summary_info += {'user-mode emulation': have_user} 4396summary_info += {'block layer': have_block} 4397summary_info += {'Install blobs': get_option('install_blobs')} 4398summary_info += {'module support': enable_modules} 4399if enable_modules 4400 summary_info += {'alternative module path': get_option('module_upgrades')} 4401endif 4402summary_info += {'fuzzing support': get_option('fuzzing')} 4403if have_system 4404 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4405endif 4406summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4407if 'simple' in get_option('trace_backends') 4408 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4409endif 4410summary_info += {'D-Bus display': dbus_display} 4411summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4412summary_info += {'Relocatable install': get_option('relocatable')} 4413summary_info += {'vhost-kernel support': have_vhost_kernel} 4414summary_info += {'vhost-net support': have_vhost_net} 4415summary_info += {'vhost-user support': have_vhost_user} 4416summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4417summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4418summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4419summary_info += {'build guest agent': have_ga} 4420summary(summary_info, bool_yn: true, section: 'Configurable features') 4421 4422# Compilation information 4423summary_info = {} 4424summary_info += {'host CPU': cpu} 4425summary_info += {'host endianness': build_machine.endian()} 4426summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4427summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4428if 'cpp' in all_languages 4429 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4430else 4431 summary_info += {'C++ compiler': false} 4432endif 4433if 'objc' in all_languages 4434 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4435else 4436 summary_info += {'Objective-C compiler': false} 4437endif 4438summary_info += {'Rust support': have_rust} 4439if have_rust 4440 summary_info += {'rustc version': rustc.version()} 4441 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4442 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4443endif 4444option_cflags = (get_option('debug') ? ['-g'] : []) 4445if get_option('optimization') != 'plain' 4446 option_cflags += ['-O' + get_option('optimization')] 4447endif 4448summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4449if 'cpp' in all_languages 4450 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4451endif 4452if 'objc' in all_languages 4453 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4454endif 4455link_args = get_option('c_link_args') 4456if link_args.length() > 0 4457 summary_info += {'LDFLAGS': ' '.join(link_args)} 4458endif 4459summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4460if 'cpp' in all_languages 4461 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4462endif 4463if 'objc' in all_languages 4464 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4465endif 4466summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4467summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4468summary_info += {'PIE': get_option('b_pie')} 4469summary_info += {'static build': get_option('prefer_static')} 4470summary_info += {'malloc trim support': has_malloc_trim} 4471summary_info += {'membarrier': have_membarrier} 4472summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4473summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4474summary_info += {'mutex debugging': get_option('debug_mutex')} 4475summary_info += {'memory allocator': get_option('malloc')} 4476summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4477summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4478summary_info += {'gcov': get_option('b_coverage')} 4479summary_info += {'thread sanitizer': get_option('tsan')} 4480summary_info += {'CFI support': get_option('cfi')} 4481if get_option('cfi') 4482 summary_info += {'CFI debug support': get_option('cfi_debug')} 4483endif 4484summary_info += {'strip binaries': get_option('strip')} 4485summary_info += {'sparse': sparse} 4486summary_info += {'mingw32 support': host_os == 'windows'} 4487summary(summary_info, bool_yn: true, section: 'Compilation') 4488 4489# snarf the cross-compilation information for tests 4490summary_info = {} 4491have_cross = false 4492foreach target: target_dirs 4493 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4494 if fs.exists(tcg_mak) 4495 config_cross_tcg = keyval.load(tcg_mak) 4496 if 'CC' in config_cross_tcg 4497 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4498 have_cross = true 4499 endif 4500 endif 4501endforeach 4502if have_cross 4503 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4504endif 4505 4506# Targets and accelerators 4507summary_info = {} 4508if have_system 4509 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4510 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4511 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4512 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4513 summary_info += {'Xen support': xen.found()} 4514 if xen.found() 4515 summary_info += {'xen ctrl version': xen.version()} 4516 endif 4517 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4518endif 4519summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4520if config_all_accel.has_key('CONFIG_TCG') 4521 if get_option('tcg_interpreter') 4522 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4523 else 4524 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4525 endif 4526 summary_info += {'TCG plugins': get_option('plugins')} 4527 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4528 if have_linux_user or have_bsd_user 4529 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4530 endif 4531endif 4532summary_info += {'target list': ' '.join(target_dirs)} 4533if have_system 4534 summary_info += {'default devices': get_option('default_devices')} 4535 summary_info += {'out of process emulation': multiprocess_allowed} 4536 summary_info += {'vfio-user server': vfio_user_server_allowed} 4537endif 4538summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4539 4540# Block layer 4541summary_info = {} 4542summary_info += {'coroutine backend': coroutine_backend} 4543summary_info += {'coroutine pool': have_coroutine_pool} 4544if have_block 4545 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4546 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4547 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4548 summary_info += {'VirtFS (9P) support': have_virtfs} 4549 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4550 summary_info += {'bochs support': get_option('bochs').allowed()} 4551 summary_info += {'cloop support': get_option('cloop').allowed()} 4552 summary_info += {'dmg support': get_option('dmg').allowed()} 4553 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4554 summary_info += {'vdi support': get_option('vdi').allowed()} 4555 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4556 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4557 summary_info += {'vpc support': get_option('vpc').allowed()} 4558 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4559 summary_info += {'qed support': get_option('qed').allowed()} 4560 summary_info += {'parallels support': get_option('parallels').allowed()} 4561 summary_info += {'FUSE exports': fuse} 4562 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4563endif 4564summary(summary_info, bool_yn: true, section: 'Block layer support') 4565 4566# Crypto 4567summary_info = {} 4568summary_info += {'TLS priority': get_option('tls_priority')} 4569summary_info += {'GNUTLS support': gnutls} 4570if gnutls.found() 4571 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4572endif 4573summary_info += {'libgcrypt': gcrypt} 4574summary_info += {'nettle': nettle} 4575if nettle.found() 4576 summary_info += {' XTS': xts != 'private'} 4577endif 4578summary_info += {'SM4 ALG support': crypto_sm4} 4579summary_info += {'AF_ALG support': have_afalg} 4580summary_info += {'rng-none': get_option('rng_none')} 4581summary_info += {'Linux keyring': have_keyring} 4582summary_info += {'Linux keyutils': keyutils} 4583summary(summary_info, bool_yn: true, section: 'Crypto') 4584 4585# UI 4586summary_info = {} 4587if host_os == 'darwin' 4588 summary_info += {'Cocoa support': cocoa} 4589endif 4590summary_info += {'SDL support': sdl} 4591summary_info += {'SDL image support': sdl_image} 4592summary_info += {'GTK support': gtk} 4593summary_info += {'pixman': pixman} 4594summary_info += {'VTE support': vte} 4595summary_info += {'PNG support': png} 4596summary_info += {'VNC support': vnc} 4597if vnc.found() 4598 summary_info += {'VNC SASL support': sasl} 4599 summary_info += {'VNC JPEG support': jpeg} 4600endif 4601summary_info += {'spice protocol support': spice_protocol} 4602if spice_protocol.found() 4603 summary_info += {' spice server support': spice} 4604endif 4605summary_info += {'curses support': curses} 4606summary_info += {'brlapi support': brlapi} 4607summary(summary_info, bool_yn: true, section: 'User interface') 4608 4609# Graphics backends 4610summary_info = {} 4611summary_info += {'VirGL support': virgl} 4612summary_info += {'Rutabaga support': rutabaga} 4613summary(summary_info, bool_yn: true, section: 'Graphics backends') 4614 4615# Audio backends 4616summary_info = {} 4617if host_os not in ['darwin', 'haiku', 'windows'] 4618 summary_info += {'OSS support': oss} 4619 summary_info += {'sndio support': sndio} 4620elif host_os == 'darwin' 4621 summary_info += {'CoreAudio support': coreaudio} 4622elif host_os == 'windows' 4623 summary_info += {'DirectSound support': dsound} 4624endif 4625if host_os == 'linux' 4626 summary_info += {'ALSA support': alsa} 4627 summary_info += {'PulseAudio support': pulse} 4628endif 4629summary_info += {'PipeWire support': pipewire} 4630summary_info += {'JACK support': jack} 4631summary(summary_info, bool_yn: true, section: 'Audio backends') 4632 4633# Network backends 4634summary_info = {} 4635if host_os == 'darwin' 4636 summary_info += {'vmnet.framework support': vmnet} 4637endif 4638summary_info += {'AF_XDP support': libxdp} 4639summary_info += {'slirp support': slirp} 4640summary_info += {'vde support': vde} 4641summary_info += {'netmap support': have_netmap} 4642summary_info += {'l2tpv3 support': have_l2tpv3} 4643summary(summary_info, bool_yn: true, section: 'Network backends') 4644 4645# Libraries 4646summary_info = {} 4647summary_info += {'libtasn1': tasn1} 4648summary_info += {'PAM': pam} 4649summary_info += {'iconv support': iconv} 4650summary_info += {'blkio support': blkio} 4651summary_info += {'curl support': curl} 4652summary_info += {'Multipath support': mpathpersist} 4653summary_info += {'Linux AIO support': libaio} 4654summary_info += {'Linux io_uring support': linux_io_uring} 4655summary_info += {'ATTR/XATTR support': libattr} 4656summary_info += {'RDMA support': rdma} 4657summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4658summary_info += {'libcap-ng support': libcap_ng} 4659summary_info += {'bpf support': libbpf} 4660summary_info += {'rbd support': rbd} 4661summary_info += {'smartcard support': cacard} 4662summary_info += {'U2F support': u2f} 4663summary_info += {'libusb': libusb} 4664summary_info += {'usb net redir': usbredir} 4665summary_info += {'OpenGL support (epoxy)': opengl} 4666summary_info += {'GBM': gbm} 4667summary_info += {'libiscsi support': libiscsi} 4668summary_info += {'libnfs support': libnfs} 4669if host_os == 'windows' 4670 if have_ga 4671 summary_info += {'QGA VSS support': have_qga_vss} 4672 endif 4673endif 4674summary_info += {'seccomp support': seccomp} 4675summary_info += {'GlusterFS support': glusterfs} 4676summary_info += {'hv-balloon support': hv_balloon} 4677summary_info += {'TPM support': have_tpm} 4678summary_info += {'libssh support': libssh} 4679summary_info += {'lzo support': lzo} 4680summary_info += {'snappy support': snappy} 4681summary_info += {'bzip2 support': libbzip2} 4682summary_info += {'lzfse support': liblzfse} 4683summary_info += {'zstd support': zstd} 4684summary_info += {'Query Processing Library support': qpl} 4685summary_info += {'UADK Library support': uadk} 4686summary_info += {'qatzip support': qatzip} 4687summary_info += {'NUMA host support': numa} 4688summary_info += {'capstone': capstone} 4689summary_info += {'libpmem support': libpmem} 4690summary_info += {'libdaxctl support': libdaxctl} 4691summary_info += {'libudev': libudev} 4692# Dummy dependency, keep .found() 4693summary_info += {'FUSE lseek': fuse_lseek.found()} 4694summary_info += {'selinux': selinux} 4695summary_info += {'libdw': libdw} 4696if host_os == 'freebsd' 4697 summary_info += {'libinotify-kqueue': inotify} 4698endif 4699summary(summary_info, bool_yn: true, section: 'Dependencies') 4700 4701if host_arch == 'unknown' 4702 message() 4703 warning('UNSUPPORTED HOST CPU') 4704 message() 4705 message('Support for CPU host architecture ' + cpu + ' is not currently') 4706 message('maintained. The QEMU project does not guarantee that QEMU will') 4707 message('compile or work on this host CPU. You can help by volunteering') 4708 message('to maintain it and providing a build host for our continuous') 4709 message('integration setup.') 4710 if get_option('tcg').allowed() and target_dirs.length() > 0 4711 message() 4712 message('configure has succeeded and you can continue to build, but') 4713 message('QEMU will use a slow interpreter to emulate the target CPU.') 4714 endif 4715endif 4716 4717if not supported_oses.contains(host_os) 4718 message() 4719 warning('UNSUPPORTED HOST OS') 4720 message() 4721 message('Support for host OS ' + host_os + 'is not currently maintained.') 4722 message('configure has succeeded and you can continue to build, but') 4723 message('the QEMU project does not guarantee that QEMU will compile or') 4724 message('work on this operating system. You can help by volunteering') 4725 message('to maintain it and providing a build host for our continuous') 4726 message('integration setup. This will ensure that future versions of QEMU') 4727 message('will keep working on ' + host_os + '.') 4728endif 4729 4730if host_arch == 'unknown' or not supported_oses.contains(host_os) 4731 message() 4732 message('If you want to help supporting QEMU on this platform, please') 4733 message('contact the developers at qemu-devel@nongnu.org.') 4734endif 4735 4736actually_reloc = get_option('relocatable') 4737# check if get_relocated_path() is actually able to relocate paths 4738if get_option('relocatable') and \ 4739 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4740 message() 4741 warning('bindir not included within prefix, the installation will not be relocatable.') 4742 actually_reloc = false 4743endif 4744if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4745 if host_os == 'windows' 4746 message() 4747 warning('Windows installs should usually be relocatable.') 4748 endif 4749 message() 4750 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4751 message('Use --disable-relocatable to remove this warning.') 4752endif 4753