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