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