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