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 'hexagon' : ['CONFIG_HEXAGON_DIS'], 3065 'hppa' : ['CONFIG_HPPA_DIS'], 3066 'i386' : ['CONFIG_I386_DIS'], 3067 'x86_64' : ['CONFIG_I386_DIS'], 3068 'm68k' : ['CONFIG_M68K_DIS'], 3069 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 3070 'mips' : ['CONFIG_MIPS_DIS'], 3071 'or1k' : ['CONFIG_OPENRISC_DIS'], 3072 'ppc' : ['CONFIG_PPC_DIS'], 3073 'riscv' : ['CONFIG_RISCV_DIS'], 3074 'rx' : ['CONFIG_RX_DIS'], 3075 's390' : ['CONFIG_S390_DIS'], 3076 'sh4' : ['CONFIG_SH4_DIS'], 3077 'sparc' : ['CONFIG_SPARC_DIS'], 3078 'xtensa' : ['CONFIG_XTENSA_DIS'], 3079 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 3080} 3081 3082have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 3083host_kconfig = \ 3084 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 3085 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 3086 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ 3087 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 3088 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 3089 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 3090 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 3091 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \ 3092 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 3093 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 3094 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 3095 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 3096 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \ 3097 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 3098 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \ 3099 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) 3100 3101ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 3102 3103default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 3104actual_target_dirs = [] 3105fdt_required = [] 3106foreach target : target_dirs 3107 config_target = { 'TARGET_NAME': target.split('-')[0] } 3108 if target.endswith('linux-user') 3109 if host_os != 'linux' 3110 if default_targets 3111 continue 3112 endif 3113 error('Target @0@ is only available on a Linux host'.format(target)) 3114 endif 3115 config_target += { 'CONFIG_LINUX_USER': 'y' } 3116 elif target.endswith('bsd-user') 3117 if host_os not in bsd_oses 3118 if default_targets 3119 continue 3120 endif 3121 error('Target @0@ is only available on a BSD host'.format(target)) 3122 endif 3123 config_target += { 'CONFIG_BSD_USER': 'y' } 3124 elif target.endswith('softmmu') 3125 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' } 3126 config_target += { 'CONFIG_SOFTMMU': 'y' } 3127 endif 3128 if target.endswith('-user') 3129 config_target += { 3130 'CONFIG_USER_ONLY': 'y', 3131 'CONFIG_QEMU_INTERP_PREFIX': 3132 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']) 3133 } 3134 endif 3135 3136 target_kconfig = [] 3137 foreach sym: accelerators 3138 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 3139 config_target += { sym: 'y' } 3140 config_all_accel += { sym: 'y' } 3141 if target in modular_tcg 3142 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 3143 else 3144 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 3145 endif 3146 target_kconfig += [ sym + '=y' ] 3147 endif 3148 endforeach 3149 if target_kconfig.length() == 0 3150 if default_targets 3151 continue 3152 endif 3153 error('No accelerator available for target @0@'.format(target)) 3154 endif 3155 3156 config_target += keyval.load('configs/targets' / target + '.mak') 3157 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 3158 3159 if 'TARGET_NEED_FDT' in config_target and not fdt.found() 3160 if default_targets 3161 warning('Disabling ' + target + ' due to missing libfdt') 3162 else 3163 fdt_required += target 3164 endif 3165 continue 3166 endif 3167 3168 actual_target_dirs += target 3169 3170 # Add default keys 3171 if 'TARGET_BASE_ARCH' not in config_target 3172 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 3173 endif 3174 if 'TARGET_ABI_DIR' not in config_target 3175 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 3176 endif 3177 if 'TARGET_BIG_ENDIAN' not in config_target 3178 config_target += {'TARGET_BIG_ENDIAN': 'n'} 3179 endif 3180 3181 foreach k, v: disassemblers 3182 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 3183 foreach sym: v 3184 config_target += { sym: 'y' } 3185 endforeach 3186 endif 3187 endforeach 3188 3189 config_target_data = configuration_data() 3190 foreach k, v: config_target 3191 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 3192 # do nothing 3193 elif ignored.contains(k) 3194 # do nothing 3195 elif k == 'TARGET_BASE_ARCH' 3196 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 3197 # not used to select files from sourcesets. 3198 config_target_data.set('TARGET_' + v.to_upper(), 1) 3199 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 3200 config_target_data.set_quoted(k, v) 3201 elif v == 'y' 3202 config_target_data.set(k, 1) 3203 elif v == 'n' 3204 config_target_data.set(k, 0) 3205 else 3206 config_target_data.set(k, v) 3207 endif 3208 endforeach 3209 config_target_data.set('QEMU_ARCH', 3210 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 3211 config_target_h += {target: configure_file(output: target + '-config-target.h', 3212 configuration: config_target_data)} 3213 3214 if target.endswith('-softmmu') 3215 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y' 3216 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN'] 3217 3218 config_input = meson.get_external_property(target, 'default') 3219 config_devices_mak = target + '-config-devices.mak' 3220 config_devices_mak = configure_file( 3221 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 3222 output: config_devices_mak, 3223 depfile: config_devices_mak + '.d', 3224 capture: true, 3225 command: [minikconf, 3226 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 3227 config_devices_mak, '@DEPFILE@', '@INPUT@', 3228 host_kconfig, target_kconfig]) 3229 3230 config_devices_data = configuration_data() 3231 config_devices = keyval.load(config_devices_mak) 3232 foreach k, v: config_devices 3233 config_devices_data.set(k, 1) 3234 endforeach 3235 config_devices_mak_list += config_devices_mak 3236 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 3237 configuration: config_devices_data)} 3238 config_target += config_devices 3239 config_all_devices += config_devices 3240 endif 3241 config_target_mak += {target: config_target} 3242endforeach 3243target_dirs = actual_target_dirs 3244 3245target_configs_h = [] 3246foreach target: target_dirs 3247 target_configs_h += config_target_h[target] 3248 target_configs_h += config_devices_h.get(target, []) 3249endforeach 3250genh += custom_target('config-poison.h', 3251 input: [target_configs_h], 3252 output: 'config-poison.h', 3253 capture: true, 3254 command: [find_program('scripts/make-config-poison.sh'), 3255 target_configs_h]) 3256 3257if fdt_required.length() > 0 3258 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3259endif 3260 3261############### 3262# Subprojects # 3263############### 3264 3265libvfio_user_dep = not_found 3266if have_system and vfio_user_server_allowed 3267 libvfio_user_proj = subproject('libvfio-user', required: true) 3268 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3269endif 3270 3271vhost_user = not_found 3272if host_os == 'linux' and have_vhost_user 3273 libvhost_user = subproject('libvhost-user') 3274 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3275endif 3276 3277libvduse = not_found 3278if have_libvduse 3279 libvduse_proj = subproject('libvduse') 3280 libvduse = libvduse_proj.get_variable('libvduse_dep') 3281endif 3282 3283##################### 3284# Generated sources # 3285##################### 3286 3287genh += configure_file(output: 'config-host.h', configuration: config_host_data) 3288 3289hxtool = find_program('scripts/hxtool') 3290shaderinclude = find_program('scripts/shaderinclude.py') 3291qapi_gen = find_program('scripts/qapi-gen.py') 3292qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3293 meson.current_source_dir() / 'scripts/qapi/commands.py', 3294 meson.current_source_dir() / 'scripts/qapi/common.py', 3295 meson.current_source_dir() / 'scripts/qapi/error.py', 3296 meson.current_source_dir() / 'scripts/qapi/events.py', 3297 meson.current_source_dir() / 'scripts/qapi/expr.py', 3298 meson.current_source_dir() / 'scripts/qapi/gen.py', 3299 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3300 meson.current_source_dir() / 'scripts/qapi/main.py', 3301 meson.current_source_dir() / 'scripts/qapi/parser.py', 3302 meson.current_source_dir() / 'scripts/qapi/schema.py', 3303 meson.current_source_dir() / 'scripts/qapi/source.py', 3304 meson.current_source_dir() / 'scripts/qapi/types.py', 3305 meson.current_source_dir() / 'scripts/qapi/visit.py', 3306 meson.current_source_dir() / 'scripts/qapi-gen.py' 3307] 3308 3309tracetool = [ 3310 python, files('scripts/tracetool.py'), 3311 '--backend=' + ','.join(get_option('trace_backends')) 3312] 3313tracetool_depends = files( 3314 'scripts/tracetool/backend/log.py', 3315 'scripts/tracetool/backend/__init__.py', 3316 'scripts/tracetool/backend/dtrace.py', 3317 'scripts/tracetool/backend/ftrace.py', 3318 'scripts/tracetool/backend/simple.py', 3319 'scripts/tracetool/backend/syslog.py', 3320 'scripts/tracetool/backend/ust.py', 3321 'scripts/tracetool/format/ust_events_c.py', 3322 'scripts/tracetool/format/ust_events_h.py', 3323 'scripts/tracetool/format/__init__.py', 3324 'scripts/tracetool/format/d.py', 3325 'scripts/tracetool/format/simpletrace_stap.py', 3326 'scripts/tracetool/format/c.py', 3327 'scripts/tracetool/format/h.py', 3328 'scripts/tracetool/format/log_stap.py', 3329 'scripts/tracetool/format/stap.py', 3330 'scripts/tracetool/__init__.py', 3331) 3332 3333qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3334 meson.current_source_dir(), 3335 get_option('pkgversion'), meson.project_version()] 3336qemu_version = custom_target('qemu-version.h', 3337 output: 'qemu-version.h', 3338 command: qemu_version_cmd, 3339 capture: true, 3340 build_by_default: true, 3341 build_always_stale: true) 3342genh += qemu_version 3343 3344hxdep = [] 3345hx_headers = [ 3346 ['qemu-options.hx', 'qemu-options.def'], 3347 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3348] 3349if have_system 3350 hx_headers += [ 3351 ['hmp-commands.hx', 'hmp-commands.h'], 3352 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3353 ] 3354endif 3355foreach d : hx_headers 3356 hxdep += custom_target(d[1], 3357 input: files(d[0]), 3358 output: d[1], 3359 capture: true, 3360 command: [hxtool, '-h', '@INPUT0@']) 3361endforeach 3362genh += hxdep 3363 3364############### 3365# Trace files # 3366############### 3367 3368# TODO: add each directory to the subdirs from its own meson.build, once 3369# we have those 3370trace_events_subdirs = [ 3371 'crypto', 3372 'qapi', 3373 'qom', 3374 'monitor', 3375 'util', 3376 'gdbstub', 3377] 3378if have_linux_user 3379 trace_events_subdirs += [ 'linux-user' ] 3380endif 3381if have_bsd_user 3382 trace_events_subdirs += [ 'bsd-user' ] 3383endif 3384if have_block 3385 trace_events_subdirs += [ 3386 'authz', 3387 'block', 3388 'chardev', 3389 'io', 3390 'nbd', 3391 'scsi', 3392 ] 3393endif 3394if have_system 3395 trace_events_subdirs += [ 3396 'accel/kvm', 3397 'audio', 3398 'backends', 3399 'backends/tpm', 3400 'ebpf', 3401 'hw/9pfs', 3402 'hw/acpi', 3403 'hw/adc', 3404 'hw/alpha', 3405 'hw/arm', 3406 'hw/audio', 3407 'hw/block', 3408 'hw/char', 3409 'hw/display', 3410 'hw/dma', 3411 'hw/fsi', 3412 'hw/hyperv', 3413 'hw/i2c', 3414 'hw/i386', 3415 'hw/i386/xen', 3416 'hw/i386/kvm', 3417 'hw/ide', 3418 'hw/input', 3419 'hw/intc', 3420 'hw/isa', 3421 'hw/mem', 3422 'hw/mips', 3423 'hw/misc', 3424 'hw/misc/macio', 3425 'hw/net', 3426 'hw/net/can', 3427 'hw/nubus', 3428 'hw/nvme', 3429 'hw/nvram', 3430 'hw/pci', 3431 'hw/pci-host', 3432 'hw/ppc', 3433 'hw/rtc', 3434 'hw/s390x', 3435 'hw/scsi', 3436 'hw/sd', 3437 'hw/sh4', 3438 'hw/sparc', 3439 'hw/sparc64', 3440 'hw/ssi', 3441 'hw/timer', 3442 'hw/tpm', 3443 'hw/ufs', 3444 'hw/usb', 3445 'hw/vfio', 3446 'hw/virtio', 3447 'hw/watchdog', 3448 'hw/xen', 3449 'hw/gpio', 3450 'migration', 3451 'net', 3452 'system', 3453 'ui', 3454 'hw/remote', 3455 ] 3456endif 3457if have_system or have_user 3458 trace_events_subdirs += [ 3459 'accel/tcg', 3460 'hw/core', 3461 'target/arm', 3462 'target/arm/hvf', 3463 'target/hppa', 3464 'target/i386', 3465 'target/i386/kvm', 3466 'target/loongarch', 3467 'target/mips/tcg', 3468 'target/ppc', 3469 'target/riscv', 3470 'target/s390x', 3471 'target/s390x/kvm', 3472 'target/sparc', 3473 ] 3474endif 3475 3476################### 3477# Collect sources # 3478################### 3479 3480authz_ss = ss.source_set() 3481blockdev_ss = ss.source_set() 3482block_ss = ss.source_set() 3483chardev_ss = ss.source_set() 3484common_ss = ss.source_set() 3485crypto_ss = ss.source_set() 3486hwcore_ss = ss.source_set() 3487io_ss = ss.source_set() 3488qmp_ss = ss.source_set() 3489qom_ss = ss.source_set() 3490system_ss = ss.source_set() 3491specific_fuzz_ss = ss.source_set() 3492specific_ss = ss.source_set() 3493stub_ss = ss.source_set() 3494trace_ss = ss.source_set() 3495user_ss = ss.source_set() 3496util_ss = ss.source_set() 3497 3498# accel modules 3499qtest_module_ss = ss.source_set() 3500tcg_module_ss = ss.source_set() 3501 3502modules = {} 3503target_modules = {} 3504hw_arch = {} 3505target_arch = {} 3506target_system_arch = {} 3507target_user_arch = {} 3508 3509# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3510# that is filled in by qapi/. 3511subdir('qapi') 3512subdir('qobject') 3513subdir('stubs') 3514subdir('trace') 3515subdir('util') 3516subdir('qom') 3517subdir('authz') 3518subdir('crypto') 3519subdir('ui') 3520subdir('gdbstub') 3521if have_system 3522 subdir('hw') 3523else 3524 subdir('hw/core') 3525endif 3526 3527if enable_modules 3528 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3529 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3530endif 3531 3532qom_ss = qom_ss.apply({}) 3533libqom = static_library('qom', qom_ss.sources() + genh, 3534 dependencies: [qom_ss.dependencies()], 3535 build_by_default: false) 3536qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3537 dependencies: qom_ss.dependencies()) 3538 3539event_loop_base = files('event-loop-base.c') 3540event_loop_base = static_library('event-loop-base', 3541 sources: event_loop_base + genh, 3542 build_by_default: false) 3543event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3544 dependencies: [qom]) 3545 3546stub_ss = stub_ss.apply({}) 3547 3548util_ss.add_all(trace_ss) 3549util_ss = util_ss.apply({}) 3550libqemuutil = static_library('qemuutil', 3551 build_by_default: false, 3552 sources: util_ss.sources() + stub_ss.sources() + genh, 3553 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3554qemuutil = declare_dependency(link_with: libqemuutil, 3555 sources: genh + version_res, 3556 dependencies: [event_loop_base]) 3557 3558if have_system or have_user 3559 decodetree = generator(find_program('scripts/decodetree.py'), 3560 output: 'decode-@BASENAME@.c.inc', 3561 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3562 subdir('libdecnumber') 3563 subdir('target') 3564endif 3565 3566subdir('audio') 3567subdir('io') 3568subdir('chardev') 3569subdir('fsdev') 3570subdir('dump') 3571 3572if have_block 3573 block_ss.add(files( 3574 'block.c', 3575 'blockjob.c', 3576 'job.c', 3577 'qemu-io-cmds.c', 3578 )) 3579 if config_host_data.get('CONFIG_REPLICATION') 3580 block_ss.add(files('replication.c')) 3581 endif 3582 3583 subdir('nbd') 3584 subdir('scsi') 3585 subdir('block') 3586 3587 blockdev_ss.add(files( 3588 'blockdev.c', 3589 'blockdev-nbd.c', 3590 'iothread.c', 3591 'job-qmp.c', 3592 )) 3593 3594 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3595 # os-win32.c does not 3596 if host_os == 'windows' 3597 system_ss.add(files('os-win32.c')) 3598 else 3599 blockdev_ss.add(files('os-posix.c')) 3600 endif 3601endif 3602 3603common_ss.add(files('cpu-common.c')) 3604specific_ss.add(files('cpu-target.c')) 3605 3606subdir('system') 3607 3608# Work around a gcc bug/misfeature wherein constant propagation looks 3609# through an alias: 3610# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3611# to guess that a const variable is always zero. Without lto, this is 3612# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3613# without lto, not even the alias is required -- we simply use different 3614# declarations in different compilation units. 3615pagevary = files('page-vary-common.c') 3616if get_option('b_lto') 3617 pagevary_flags = ['-fno-lto'] 3618 if get_option('cfi') 3619 pagevary_flags += '-fno-sanitize=cfi-icall' 3620 endif 3621 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3622 c_args: pagevary_flags) 3623 pagevary = declare_dependency(link_with: pagevary) 3624endif 3625common_ss.add(pagevary) 3626specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3627 3628subdir('backends') 3629subdir('disas') 3630subdir('migration') 3631subdir('monitor') 3632subdir('net') 3633subdir('replay') 3634subdir('semihosting') 3635subdir('stats') 3636subdir('tcg') 3637subdir('fpu') 3638subdir('accel') 3639subdir('plugins') 3640subdir('ebpf') 3641 3642common_user_inc = [] 3643 3644subdir('common-user') 3645subdir('bsd-user') 3646subdir('linux-user') 3647 3648# needed for fuzzing binaries 3649subdir('tests/qtest/libqos') 3650subdir('tests/qtest/fuzz') 3651 3652# accel modules 3653tcg_real_module_ss = ss.source_set() 3654tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3655specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3656target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3657 'tcg': tcg_real_module_ss }} 3658 3659############################################## 3660# Internal static_libraries and dependencies # 3661############################################## 3662 3663modinfo_collect = find_program('scripts/modinfo-collect.py') 3664modinfo_generate = find_program('scripts/modinfo-generate.py') 3665modinfo_files = [] 3666 3667block_mods = [] 3668system_mods = [] 3669emulator_modules = [] 3670foreach d, list : modules 3671 if not (d == 'block' ? have_block : have_system) 3672 continue 3673 endif 3674 3675 foreach m, module_ss : list 3676 if enable_modules 3677 module_ss.add(modulecommon) 3678 module_ss = module_ss.apply(config_all_devices, strict: false) 3679 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3680 dependencies: module_ss.dependencies(), pic: true) 3681 if d == 'block' 3682 block_mods += sl 3683 else 3684 system_mods += sl 3685 endif 3686 emulator_modules += shared_module(sl.name(), 3687 name_prefix: '', 3688 objects: sl.extract_all_objects(recursive: false), 3689 dependencies: module_ss.dependencies(), 3690 install: true, 3691 install_dir: qemu_moddir) 3692 if module_ss.sources() != [] 3693 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3694 # input. Sources can be used multiple times but objects are 3695 # unique when it comes to lookup in compile_commands.json. 3696 # Depnds on a mesion version with 3697 # https://github.com/mesonbuild/meson/pull/8900 3698 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3699 output: d + '-' + m + '.modinfo', 3700 input: module_ss.sources() + genh, 3701 capture: true, 3702 command: [modinfo_collect, module_ss.sources()]) 3703 endif 3704 else 3705 if d == 'block' 3706 block_ss.add_all(module_ss) 3707 else 3708 system_ss.add_all(module_ss) 3709 endif 3710 endif 3711 endforeach 3712endforeach 3713 3714foreach d, list : target_modules 3715 foreach m, module_ss : list 3716 if enable_modules 3717 module_ss.add(modulecommon) 3718 foreach target : target_dirs 3719 if target.endswith('-softmmu') 3720 config_target = config_target_mak[target] 3721 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3722 c_args = ['-DCOMPILING_PER_TARGET', 3723 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3724 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3725 target_module_ss = module_ss.apply(config_target, strict: false) 3726 if target_module_ss.sources() != [] 3727 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3728 sl = static_library(module_name, 3729 [genh, target_module_ss.sources()], 3730 dependencies: target_module_ss.dependencies(), 3731 include_directories: target_inc, 3732 c_args: c_args, 3733 pic: true) 3734 system_mods += sl 3735 emulator_modules += shared_module(sl.name(), 3736 name_prefix: '', 3737 objects: sl.extract_all_objects(recursive: false), 3738 dependencies: target_module_ss.dependencies(), 3739 install: true, 3740 install_dir: qemu_moddir) 3741 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3742 modinfo_files += custom_target(module_name + '.modinfo', 3743 output: module_name + '.modinfo', 3744 input: target_module_ss.sources() + genh, 3745 capture: true, 3746 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3747 endif 3748 endif 3749 endforeach 3750 else 3751 specific_ss.add_all(module_ss) 3752 endif 3753 endforeach 3754endforeach 3755 3756if enable_modules 3757 foreach target : target_dirs 3758 if target.endswith('-softmmu') 3759 config_target = config_target_mak[target] 3760 config_devices_mak = target + '-config-devices.mak' 3761 modinfo_src = custom_target('modinfo-' + target + '.c', 3762 output: 'modinfo-' + target + '.c', 3763 input: modinfo_files, 3764 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3765 capture: true) 3766 3767 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3768 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3769 3770 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3771 hw_arch[arch].add(modinfo_dep) 3772 endif 3773 endforeach 3774 3775 if emulator_modules.length() > 0 3776 alias_target('modules', emulator_modules) 3777 endif 3778endif 3779 3780nm = find_program('nm') 3781undefsym = find_program('scripts/undefsym.py') 3782block_syms = custom_target('block.syms', output: 'block.syms', 3783 input: [libqemuutil, block_mods], 3784 capture: true, 3785 command: [undefsym, nm, '@INPUT@']) 3786qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3787 input: [libqemuutil, system_mods], 3788 capture: true, 3789 command: [undefsym, nm, '@INPUT@']) 3790 3791authz_ss = authz_ss.apply({}) 3792libauthz = static_library('authz', authz_ss.sources() + genh, 3793 dependencies: [authz_ss.dependencies()], 3794 build_by_default: false) 3795 3796authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3797 dependencies: [authz_ss.dependencies(), qom]) 3798 3799crypto_ss = crypto_ss.apply({}) 3800libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3801 dependencies: [crypto_ss.dependencies()], 3802 build_by_default: false) 3803 3804crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3805 dependencies: [crypto_ss.dependencies(), authz, qom]) 3806 3807io_ss = io_ss.apply({}) 3808libio = static_library('io', io_ss.sources() + genh, 3809 dependencies: [io_ss.dependencies()], 3810 link_with: libqemuutil, 3811 build_by_default: false) 3812 3813io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3814 dependencies: [io_ss.dependencies(), crypto, qom]) 3815 3816libmigration = static_library('migration', sources: migration_files + genh, 3817 build_by_default: false) 3818migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3819 dependencies: [qom, io]) 3820system_ss.add(migration) 3821 3822block_ss = block_ss.apply({}) 3823libblock = static_library('block', block_ss.sources() + genh, 3824 dependencies: block_ss.dependencies(), 3825 build_by_default: false) 3826 3827block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3828 dependencies: [block_ss.dependencies(), crypto, io]) 3829 3830blockdev_ss = blockdev_ss.apply({}) 3831libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3832 dependencies: blockdev_ss.dependencies(), 3833 build_by_default: false) 3834 3835blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3836 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3837 3838qmp_ss = qmp_ss.apply({}) 3839libqmp = static_library('qmp', qmp_ss.sources() + genh, 3840 dependencies: qmp_ss.dependencies(), 3841 build_by_default: false) 3842 3843qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3844 dependencies: qmp_ss.dependencies()) 3845 3846libchardev = static_library('chardev', chardev_ss.sources() + genh, 3847 dependencies: chardev_ss.dependencies(), 3848 build_by_default: false) 3849 3850chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 3851 dependencies: chardev_ss.dependencies()) 3852 3853hwcore_ss = hwcore_ss.apply({}) 3854libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3855 build_by_default: false) 3856hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 3857common_ss.add(hwcore) 3858 3859########### 3860# Targets # 3861########### 3862 3863system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3864common_ss.add(qom, qemuutil) 3865 3866common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 3867common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3868 3869# Note that this library is never used directly (only through extract_objects) 3870# and is not built by default; therefore, source files not used by the build 3871# configuration will be in build.ninja, but are never built by default. 3872common_all = static_library('common', 3873 build_by_default: false, 3874 sources: common_ss.all_sources() + genh, 3875 include_directories: common_user_inc, 3876 implicit_include_directories: false, 3877 dependencies: common_ss.all_dependencies()) 3878 3879feature_to_c = find_program('scripts/feature_to_c.py') 3880 3881if host_os == 'darwin' 3882 entitlement = find_program('scripts/entitlement.sh') 3883endif 3884 3885traceable = [] 3886emulators = {} 3887foreach target : target_dirs 3888 config_target = config_target_mak[target] 3889 target_name = config_target['TARGET_NAME'] 3890 target_base_arch = config_target['TARGET_BASE_ARCH'] 3891 arch_srcs = [config_target_h[target]] 3892 arch_deps = [] 3893 c_args = ['-DCOMPILING_PER_TARGET', 3894 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3895 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3896 link_args = emulator_link_args 3897 3898 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3899 if host_os == 'linux' 3900 target_inc += include_directories('linux-headers', is_system: true) 3901 endif 3902 if target.endswith('-softmmu') 3903 target_type='system' 3904 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 3905 arch_srcs += t.sources() 3906 arch_deps += t.dependencies() 3907 3908 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3909 if hw_arch.has_key(hw_dir) 3910 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3911 arch_srcs += hw.sources() 3912 arch_deps += hw.dependencies() 3913 endif 3914 3915 arch_srcs += config_devices_h[target] 3916 link_args += ['@block.syms', '@qemu.syms'] 3917 else 3918 abi = config_target['TARGET_ABI_DIR'] 3919 target_type='user' 3920 target_inc += common_user_inc 3921 if target_base_arch in target_user_arch 3922 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3923 arch_srcs += t.sources() 3924 arch_deps += t.dependencies() 3925 endif 3926 if 'CONFIG_LINUX_USER' in config_target 3927 base_dir = 'linux-user' 3928 endif 3929 if 'CONFIG_BSD_USER' in config_target 3930 base_dir = 'bsd-user' 3931 target_inc += include_directories('bsd-user/' / host_os) 3932 target_inc += include_directories('bsd-user/host/' / host_arch) 3933 dir = base_dir / abi 3934 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3935 endif 3936 target_inc += include_directories( 3937 base_dir, 3938 base_dir / abi, 3939 ) 3940 if 'CONFIG_LINUX_USER' in config_target 3941 dir = base_dir / abi 3942 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3943 if config_target.has_key('TARGET_SYSTBL_ABI') 3944 arch_srcs += \ 3945 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3946 extra_args : config_target['TARGET_SYSTBL_ABI']) 3947 endif 3948 endif 3949 endif 3950 3951 if 'TARGET_XML_FILES' in config_target 3952 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3953 output: target + '-gdbstub-xml.c', 3954 input: files(config_target['TARGET_XML_FILES'].split()), 3955 command: [feature_to_c, '@INPUT@'], 3956 capture: true) 3957 arch_srcs += gdbstub_xml 3958 endif 3959 3960 t = target_arch[target_base_arch].apply(config_target, strict: false) 3961 arch_srcs += t.sources() 3962 arch_deps += t.dependencies() 3963 3964 target_common = common_ss.apply(config_target, strict: false) 3965 objects = common_all.extract_objects(target_common.sources()) 3966 arch_deps += target_common.dependencies() 3967 3968 target_specific = specific_ss.apply(config_target, strict: false) 3969 arch_srcs += target_specific.sources() 3970 arch_deps += target_specific.dependencies() 3971 3972 # allow using headers from the dependencies but do not include the sources, 3973 # because this emulator only needs those in "objects". For external 3974 # dependencies, the full dependency is included below in the executable. 3975 lib_deps = [] 3976 foreach dep : arch_deps 3977 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 3978 endforeach 3979 3980 lib = static_library('qemu-' + target, 3981 sources: arch_srcs + genh, 3982 dependencies: lib_deps, 3983 objects: objects, 3984 include_directories: target_inc, 3985 c_args: c_args, 3986 build_by_default: false) 3987 3988 if target.endswith('-softmmu') 3989 execs = [{ 3990 'name': 'qemu-system-' + target_name, 3991 'win_subsystem': 'console', 3992 'sources': files('system/main.c'), 3993 'dependencies': [] 3994 }] 3995 if host_os == 'windows' and (sdl.found() or gtk.found()) 3996 execs += [{ 3997 'name': 'qemu-system-' + target_name + 'w', 3998 'win_subsystem': 'windows', 3999 'sources': files('system/main.c'), 4000 'dependencies': [] 4001 }] 4002 endif 4003 if get_option('fuzzing') 4004 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4005 execs += [{ 4006 'name': 'qemu-fuzz-' + target_name, 4007 'win_subsystem': 'console', 4008 'sources': specific_fuzz.sources(), 4009 'dependencies': specific_fuzz.dependencies(), 4010 }] 4011 endif 4012 else 4013 execs = [{ 4014 'name': 'qemu-' + target_name, 4015 'win_subsystem': 'console', 4016 'sources': [], 4017 'dependencies': [] 4018 }] 4019 endif 4020 foreach exe: execs 4021 exe_name = exe['name'] 4022 if host_os == 'darwin' 4023 exe_name += '-unsigned' 4024 endif 4025 4026 emulator = executable(exe_name, exe['sources'], 4027 install: true, 4028 c_args: c_args, 4029 dependencies: arch_deps + exe['dependencies'], 4030 objects: lib.extract_all_objects(recursive: true), 4031 link_depends: [block_syms, qemu_syms], 4032 link_args: link_args, 4033 win_subsystem: exe['win_subsystem']) 4034 4035 if host_os == 'darwin' 4036 icon = 'pc-bios/qemu.rsrc' 4037 build_input = [emulator, files(icon)] 4038 install_input = [ 4039 get_option('bindir') / exe_name, 4040 meson.current_source_dir() / icon 4041 ] 4042 if 'CONFIG_HVF' in config_target 4043 entitlements = 'accel/hvf/entitlements.plist' 4044 build_input += files(entitlements) 4045 install_input += meson.current_source_dir() / entitlements 4046 endif 4047 4048 emulators += {exe['name'] : custom_target(exe['name'], 4049 input: build_input, 4050 output: exe['name'], 4051 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4052 } 4053 4054 meson.add_install_script(entitlement, '--install', 4055 get_option('bindir') / exe['name'], 4056 install_input) 4057 else 4058 emulators += {exe['name']: emulator} 4059 endif 4060 4061 traceable += [{ 4062 'exe': exe['name'], 4063 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4064 }] 4065 4066 endforeach 4067endforeach 4068 4069# Other build targets 4070 4071if get_option('plugins') 4072 install_headers('include/qemu/qemu-plugin.h') 4073 if host_os == 'windows' 4074 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4075 # so that plugin authors can compile against it. 4076 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4077 endif 4078endif 4079 4080subdir('qga') 4081 4082# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4083# when we don't build tools or system 4084if xkbcommon.found() 4085 # used for the update-keymaps target, so include rules even if !have_tools 4086 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4087 dependencies: [qemuutil, xkbcommon], install: have_tools) 4088endif 4089 4090if have_tools 4091 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4092 link_args: '@block.syms', link_depends: block_syms, 4093 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4094 qemu_io = executable('qemu-io', files('qemu-io.c'), 4095 link_args: '@block.syms', link_depends: block_syms, 4096 dependencies: [block, qemuutil], install: true) 4097 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4098 link_args: '@block.syms', link_depends: block_syms, 4099 dependencies: [blockdev, qemuutil, selinux], 4100 install: true) 4101 4102 subdir('storage-daemon') 4103 4104 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4105 traceable += [{ 4106 'exe': exe, 4107 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4108 }] 4109 endforeach 4110 4111 subdir('contrib/elf2dmp') 4112 4113 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4114 dependencies: qemuutil, 4115 install: true) 4116 4117 if have_vhost_user 4118 subdir('contrib/vhost-user-blk') 4119 subdir('contrib/vhost-user-gpu') 4120 subdir('contrib/vhost-user-input') 4121 subdir('contrib/vhost-user-scsi') 4122 endif 4123 4124 if host_os == 'linux' 4125 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4126 dependencies: [qemuutil, libcap_ng], 4127 install: true, 4128 install_dir: get_option('libexecdir')) 4129 4130 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4131 dependencies: [authz, crypto, io, qom, qemuutil, 4132 libcap_ng, mpathpersist], 4133 install: true) 4134 4135 if cpu in ['x86', 'x86_64'] 4136 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4137 dependencies: [authz, crypto, io, qom, qemuutil, 4138 libcap_ng, mpathpersist], 4139 install: true) 4140 endif 4141 endif 4142 4143 if have_ivshmem 4144 subdir('contrib/ivshmem-client') 4145 subdir('contrib/ivshmem-server') 4146 endif 4147endif 4148 4149if stap.found() 4150 foreach t: traceable 4151 foreach stp: [ 4152 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4153 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4154 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4155 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4156 ] 4157 cmd = [ 4158 tracetool, '--group=all', '--format=' + stp['fmt'], 4159 '--binary=' + stp['bin'], 4160 '--probe-prefix=' + t['probe-prefix'], 4161 '@INPUT@', '@OUTPUT@' 4162 ] 4163 4164 custom_target(t['exe'] + stp['ext'], 4165 input: trace_events_all, 4166 output: t['exe'] + stp['ext'], 4167 install: stp['install'], 4168 install_dir: get_option('datadir') / 'systemtap/tapset', 4169 command: cmd, 4170 depend_files: tracetool_depends) 4171 endforeach 4172 endforeach 4173endif 4174 4175subdir('scripts') 4176subdir('tools') 4177subdir('pc-bios') 4178subdir('docs') 4179subdir('tests') 4180if gtk.found() 4181 subdir('po') 4182endif 4183 4184if host_machine.system() == 'windows' 4185 nsis_cmd = [ 4186 find_program('scripts/nsis.py'), 4187 '@OUTPUT@', 4188 get_option('prefix'), 4189 meson.current_source_dir(), 4190 glib_pc.get_variable('bindir'), 4191 host_machine.cpu(), 4192 '--', 4193 '-DDISPLAYVERSION=' + meson.project_version(), 4194 ] 4195 if build_docs 4196 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4197 endif 4198 if gtk.found() 4199 nsis_cmd += '-DCONFIG_GTK=y' 4200 endif 4201 4202 nsis = custom_target('nsis', 4203 output: 'qemu-setup-' + meson.project_version() + '.exe', 4204 input: files('qemu.nsi'), 4205 build_always_stale: true, 4206 command: nsis_cmd + ['@INPUT@']) 4207 alias_target('installer', nsis) 4208endif 4209 4210######################### 4211# Configuration summary # 4212######################### 4213 4214# Build environment 4215summary_info = {} 4216summary_info += {'Build directory': meson.current_build_dir()} 4217summary_info += {'Source path': meson.current_source_dir()} 4218summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4219summary(summary_info, bool_yn: true, section: 'Build environment') 4220 4221# Directories 4222summary_info += {'Install prefix': get_option('prefix')} 4223summary_info += {'BIOS directory': qemu_datadir} 4224pathsep = host_os == 'windows' ? ';' : ':' 4225summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4226summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4227summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4228summary_info += {'module directory': qemu_moddir} 4229summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4230summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4231summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4232if host_os != 'windows' 4233 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4234 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4235else 4236 summary_info += {'local state directory': 'queried at runtime'} 4237endif 4238summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4239summary(summary_info, bool_yn: true, section: 'Directories') 4240 4241# Host binaries 4242summary_info = {} 4243summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4244summary_info += {'sphinx-build': sphinx_build} 4245 4246# FIXME: the [binaries] section of machine files, which can be probed 4247# with find_program(), would be great for passing gdb and genisoimage 4248# paths from configure to Meson. However, there seems to be no way to 4249# hide a program (for example if gdb is too old). 4250if config_host.has_key('GDB') 4251 summary_info += {'gdb': config_host['GDB']} 4252endif 4253summary_info += {'iasl': iasl} 4254summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4255if host_os == 'windows' and have_ga 4256 summary_info += {'wixl': wixl} 4257endif 4258if slirp.found() and have_system 4259 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4260endif 4261summary(summary_info, bool_yn: true, section: 'Host binaries') 4262 4263# Configurable features 4264summary_info = {} 4265summary_info += {'Documentation': build_docs} 4266summary_info += {'system-mode emulation': have_system} 4267summary_info += {'user-mode emulation': have_user} 4268summary_info += {'block layer': have_block} 4269summary_info += {'Install blobs': get_option('install_blobs')} 4270summary_info += {'module support': enable_modules} 4271if enable_modules 4272 summary_info += {'alternative module path': get_option('module_upgrades')} 4273endif 4274summary_info += {'fuzzing support': get_option('fuzzing')} 4275if have_system 4276 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4277endif 4278summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4279if 'simple' in get_option('trace_backends') 4280 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4281endif 4282summary_info += {'D-Bus display': dbus_display} 4283summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4284summary_info += {'Relocatable install': get_option('relocatable')} 4285summary_info += {'vhost-kernel support': have_vhost_kernel} 4286summary_info += {'vhost-net support': have_vhost_net} 4287summary_info += {'vhost-user support': have_vhost_user} 4288summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4289summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4290summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4291summary_info += {'build guest agent': have_ga} 4292summary(summary_info, bool_yn: true, section: 'Configurable features') 4293 4294# Compilation information 4295summary_info = {} 4296summary_info += {'host CPU': cpu} 4297summary_info += {'host endianness': build_machine.endian()} 4298summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4299summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4300if 'cpp' in all_languages 4301 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4302else 4303 summary_info += {'C++ compiler': false} 4304endif 4305if 'objc' in all_languages 4306 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4307else 4308 summary_info += {'Objective-C compiler': false} 4309endif 4310option_cflags = (get_option('debug') ? ['-g'] : []) 4311if get_option('optimization') != 'plain' 4312 option_cflags += ['-O' + get_option('optimization')] 4313endif 4314summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4315if 'cpp' in all_languages 4316 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4317endif 4318if 'objc' in all_languages 4319 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4320endif 4321link_args = get_option('c_link_args') 4322if link_args.length() > 0 4323 summary_info += {'LDFLAGS': ' '.join(link_args)} 4324endif 4325summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4326if 'cpp' in all_languages 4327 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4328endif 4329if 'objc' in all_languages 4330 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4331endif 4332summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4333summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4334summary_info += {'PIE': get_option('b_pie')} 4335summary_info += {'static build': get_option('prefer_static')} 4336summary_info += {'malloc trim support': has_malloc_trim} 4337summary_info += {'membarrier': have_membarrier} 4338summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4339summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4340summary_info += {'mutex debugging': get_option('debug_mutex')} 4341summary_info += {'memory allocator': get_option('malloc')} 4342summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4343summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4344summary_info += {'gcov': get_option('b_coverage')} 4345summary_info += {'thread sanitizer': get_option('tsan')} 4346summary_info += {'CFI support': get_option('cfi')} 4347if get_option('cfi') 4348 summary_info += {'CFI debug support': get_option('cfi_debug')} 4349endif 4350summary_info += {'strip binaries': get_option('strip')} 4351summary_info += {'sparse': sparse} 4352summary_info += {'mingw32 support': host_os == 'windows'} 4353summary(summary_info, bool_yn: true, section: 'Compilation') 4354 4355# snarf the cross-compilation information for tests 4356summary_info = {} 4357have_cross = false 4358foreach target: target_dirs 4359 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4360 if fs.exists(tcg_mak) 4361 config_cross_tcg = keyval.load(tcg_mak) 4362 if 'CC' in config_cross_tcg 4363 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4364 have_cross = true 4365 endif 4366 endif 4367endforeach 4368if have_cross 4369 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4370endif 4371 4372# Targets and accelerators 4373summary_info = {} 4374if have_system 4375 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4376 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4377 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4378 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4379 summary_info += {'Xen support': xen.found()} 4380 if xen.found() 4381 summary_info += {'xen ctrl version': xen.version()} 4382 endif 4383 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4384endif 4385summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4386if config_all_accel.has_key('CONFIG_TCG') 4387 if get_option('tcg_interpreter') 4388 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4389 else 4390 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4391 endif 4392 summary_info += {'TCG plugins': get_option('plugins')} 4393 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4394 if have_linux_user or have_bsd_user 4395 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4396 endif 4397endif 4398summary_info += {'target list': ' '.join(target_dirs)} 4399if have_system 4400 summary_info += {'default devices': get_option('default_devices')} 4401 summary_info += {'out of process emulation': multiprocess_allowed} 4402 summary_info += {'vfio-user server': vfio_user_server_allowed} 4403endif 4404summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4405 4406# Block layer 4407summary_info = {} 4408summary_info += {'coroutine backend': coroutine_backend} 4409summary_info += {'coroutine pool': have_coroutine_pool} 4410if have_block 4411 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4412 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4413 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4414 summary_info += {'VirtFS (9P) support': have_virtfs} 4415 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4416 summary_info += {'bochs support': get_option('bochs').allowed()} 4417 summary_info += {'cloop support': get_option('cloop').allowed()} 4418 summary_info += {'dmg support': get_option('dmg').allowed()} 4419 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4420 summary_info += {'vdi support': get_option('vdi').allowed()} 4421 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4422 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4423 summary_info += {'vpc support': get_option('vpc').allowed()} 4424 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4425 summary_info += {'qed support': get_option('qed').allowed()} 4426 summary_info += {'parallels support': get_option('parallels').allowed()} 4427 summary_info += {'FUSE exports': fuse} 4428 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4429endif 4430summary(summary_info, bool_yn: true, section: 'Block layer support') 4431 4432# Crypto 4433summary_info = {} 4434summary_info += {'TLS priority': get_option('tls_priority')} 4435summary_info += {'GNUTLS support': gnutls} 4436if gnutls.found() 4437 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4438endif 4439summary_info += {'libgcrypt': gcrypt} 4440summary_info += {'nettle': nettle} 4441if nettle.found() 4442 summary_info += {' XTS': xts != 'private'} 4443endif 4444summary_info += {'SM4 ALG support': crypto_sm4} 4445summary_info += {'AF_ALG support': have_afalg} 4446summary_info += {'rng-none': get_option('rng_none')} 4447summary_info += {'Linux keyring': have_keyring} 4448summary_info += {'Linux keyutils': keyutils} 4449summary(summary_info, bool_yn: true, section: 'Crypto') 4450 4451# UI 4452summary_info = {} 4453if host_os == 'darwin' 4454 summary_info += {'Cocoa support': cocoa} 4455endif 4456summary_info += {'SDL support': sdl} 4457summary_info += {'SDL image support': sdl_image} 4458summary_info += {'GTK support': gtk} 4459summary_info += {'pixman': pixman} 4460summary_info += {'VTE support': vte} 4461summary_info += {'PNG support': png} 4462summary_info += {'VNC support': vnc} 4463if vnc.found() 4464 summary_info += {'VNC SASL support': sasl} 4465 summary_info += {'VNC JPEG support': jpeg} 4466endif 4467summary_info += {'spice protocol support': spice_protocol} 4468if spice_protocol.found() 4469 summary_info += {' spice server support': spice} 4470endif 4471summary_info += {'curses support': curses} 4472summary_info += {'brlapi support': brlapi} 4473summary(summary_info, bool_yn: true, section: 'User interface') 4474 4475# Graphics backends 4476summary_info = {} 4477summary_info += {'VirGL support': virgl} 4478summary_info += {'Rutabaga support': rutabaga} 4479summary(summary_info, bool_yn: true, section: 'Graphics backends') 4480 4481# Audio backends 4482summary_info = {} 4483if host_os not in ['darwin', 'haiku', 'windows'] 4484 summary_info += {'OSS support': oss} 4485 summary_info += {'sndio support': sndio} 4486elif host_os == 'darwin' 4487 summary_info += {'CoreAudio support': coreaudio} 4488elif host_os == 'windows' 4489 summary_info += {'DirectSound support': dsound} 4490endif 4491if host_os == 'linux' 4492 summary_info += {'ALSA support': alsa} 4493 summary_info += {'PulseAudio support': pulse} 4494endif 4495summary_info += {'PipeWire support': pipewire} 4496summary_info += {'JACK support': jack} 4497summary(summary_info, bool_yn: true, section: 'Audio backends') 4498 4499# Network backends 4500summary_info = {} 4501if host_os == 'darwin' 4502 summary_info += {'vmnet.framework support': vmnet} 4503endif 4504summary_info += {'AF_XDP support': libxdp} 4505summary_info += {'slirp support': slirp} 4506summary_info += {'vde support': vde} 4507summary_info += {'netmap support': have_netmap} 4508summary_info += {'l2tpv3 support': have_l2tpv3} 4509summary(summary_info, bool_yn: true, section: 'Network backends') 4510 4511# Libraries 4512summary_info = {} 4513summary_info += {'libtasn1': tasn1} 4514summary_info += {'PAM': pam} 4515summary_info += {'iconv support': iconv} 4516summary_info += {'blkio support': blkio} 4517summary_info += {'curl support': curl} 4518summary_info += {'Multipath support': mpathpersist} 4519summary_info += {'Linux AIO support': libaio} 4520summary_info += {'Linux io_uring support': linux_io_uring} 4521summary_info += {'ATTR/XATTR support': libattr} 4522summary_info += {'RDMA support': rdma} 4523summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4524summary_info += {'libcap-ng support': libcap_ng} 4525summary_info += {'bpf support': libbpf} 4526summary_info += {'rbd support': rbd} 4527summary_info += {'smartcard support': cacard} 4528summary_info += {'U2F support': u2f} 4529summary_info += {'libusb': libusb} 4530summary_info += {'usb net redir': usbredir} 4531summary_info += {'OpenGL support (epoxy)': opengl} 4532summary_info += {'GBM': gbm} 4533summary_info += {'libiscsi support': libiscsi} 4534summary_info += {'libnfs support': libnfs} 4535if host_os == 'windows' 4536 if have_ga 4537 summary_info += {'QGA VSS support': have_qga_vss} 4538 endif 4539endif 4540summary_info += {'seccomp support': seccomp} 4541summary_info += {'GlusterFS support': glusterfs} 4542summary_info += {'hv-balloon support': hv_balloon} 4543summary_info += {'TPM support': have_tpm} 4544summary_info += {'libssh support': libssh} 4545summary_info += {'lzo support': lzo} 4546summary_info += {'snappy support': snappy} 4547summary_info += {'bzip2 support': libbzip2} 4548summary_info += {'lzfse support': liblzfse} 4549summary_info += {'zstd support': zstd} 4550summary_info += {'Query Processing Library support': qpl} 4551summary_info += {'UADK Library support': uadk} 4552summary_info += {'qatzip support': qatzip} 4553summary_info += {'NUMA host support': numa} 4554summary_info += {'capstone': capstone} 4555summary_info += {'libpmem support': libpmem} 4556summary_info += {'libdaxctl support': libdaxctl} 4557summary_info += {'libudev': libudev} 4558# Dummy dependency, keep .found() 4559summary_info += {'FUSE lseek': fuse_lseek.found()} 4560summary_info += {'selinux': selinux} 4561summary_info += {'libdw': libdw} 4562if host_os == 'freebsd' 4563 summary_info += {'libinotify-kqueue': inotify} 4564endif 4565summary(summary_info, bool_yn: true, section: 'Dependencies') 4566 4567if host_arch == 'unknown' 4568 message() 4569 warning('UNSUPPORTED HOST CPU') 4570 message() 4571 message('Support for CPU host architecture ' + cpu + ' is not currently') 4572 message('maintained. The QEMU project does not guarantee that QEMU will') 4573 message('compile or work on this host CPU. You can help by volunteering') 4574 message('to maintain it and providing a build host for our continuous') 4575 message('integration setup.') 4576 if get_option('tcg').allowed() and target_dirs.length() > 0 4577 message() 4578 message('configure has succeeded and you can continue to build, but') 4579 message('QEMU will use a slow interpreter to emulate the target CPU.') 4580 endif 4581endif 4582 4583if not supported_oses.contains(host_os) 4584 message() 4585 warning('UNSUPPORTED HOST OS') 4586 message() 4587 message('Support for host OS ' + host_os + 'is not currently maintained.') 4588 message('configure has succeeded and you can continue to build, but') 4589 message('the QEMU project does not guarantee that QEMU will compile or') 4590 message('work on this operating system. You can help by volunteering') 4591 message('to maintain it and providing a build host for our continuous') 4592 message('integration setup. This will ensure that future versions of QEMU') 4593 message('will keep working on ' + host_os + '.') 4594endif 4595 4596if host_arch == 'unknown' or not supported_oses.contains(host_os) 4597 message() 4598 message('If you want to help supporting QEMU on this platform, please') 4599 message('contact the developers at qemu-devel@nongnu.org.') 4600endif 4601 4602actually_reloc = get_option('relocatable') 4603# check if get_relocated_path() is actually able to relocate paths 4604if get_option('relocatable') and \ 4605 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4606 message() 4607 warning('bindir not included within prefix, the installation will not be relocatable.') 4608 actually_reloc = false 4609endif 4610if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4611 if host_os == 'windows' 4612 message() 4613 warning('Windows installs should usually be relocatable.') 4614 endif 4615 message() 4616 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4617 message('Use --disable-relocatable to remove this warning.') 4618endif 4619