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