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