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