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