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