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