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 3349 # Apart from procedural macros, our Rust executables will often link 3350 # with C code, so include all the libraries that C code needs. This 3351 # is safe; https://github.com/rust-lang/rust/pull/54675 says that 3352 # passing -nodefaultlibs to the linker "was more ideological to 3353 # start with than anything". 3354 add_project_arguments(rustc_args + ['-C', 'default-linker-libraries'], 3355 native: false, language: 'rust') 3356 3357 add_project_arguments(rustc_args, native: true, language: 'rust') 3358endif 3359 3360hxtool = find_program('scripts/hxtool') 3361shaderinclude = find_program('scripts/shaderinclude.py') 3362qapi_gen = find_program('scripts/qapi-gen.py') 3363qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3364 meson.current_source_dir() / 'scripts/qapi/commands.py', 3365 meson.current_source_dir() / 'scripts/qapi/common.py', 3366 meson.current_source_dir() / 'scripts/qapi/error.py', 3367 meson.current_source_dir() / 'scripts/qapi/events.py', 3368 meson.current_source_dir() / 'scripts/qapi/expr.py', 3369 meson.current_source_dir() / 'scripts/qapi/gen.py', 3370 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3371 meson.current_source_dir() / 'scripts/qapi/main.py', 3372 meson.current_source_dir() / 'scripts/qapi/parser.py', 3373 meson.current_source_dir() / 'scripts/qapi/schema.py', 3374 meson.current_source_dir() / 'scripts/qapi/source.py', 3375 meson.current_source_dir() / 'scripts/qapi/types.py', 3376 meson.current_source_dir() / 'scripts/qapi/visit.py', 3377 meson.current_source_dir() / 'scripts/qapi-gen.py' 3378] 3379 3380tracetool = [ 3381 python, files('scripts/tracetool.py'), 3382 '--backend=' + ','.join(get_option('trace_backends')) 3383] 3384tracetool_depends = files( 3385 'scripts/tracetool/backend/log.py', 3386 'scripts/tracetool/backend/__init__.py', 3387 'scripts/tracetool/backend/dtrace.py', 3388 'scripts/tracetool/backend/ftrace.py', 3389 'scripts/tracetool/backend/simple.py', 3390 'scripts/tracetool/backend/syslog.py', 3391 'scripts/tracetool/backend/ust.py', 3392 'scripts/tracetool/format/ust_events_c.py', 3393 'scripts/tracetool/format/ust_events_h.py', 3394 'scripts/tracetool/format/__init__.py', 3395 'scripts/tracetool/format/d.py', 3396 'scripts/tracetool/format/simpletrace_stap.py', 3397 'scripts/tracetool/format/c.py', 3398 'scripts/tracetool/format/h.py', 3399 'scripts/tracetool/format/log_stap.py', 3400 'scripts/tracetool/format/stap.py', 3401 'scripts/tracetool/__init__.py', 3402) 3403 3404qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3405 meson.current_source_dir(), 3406 get_option('pkgversion'), meson.project_version()] 3407qemu_version = custom_target('qemu-version.h', 3408 output: 'qemu-version.h', 3409 command: qemu_version_cmd, 3410 capture: true, 3411 build_by_default: true, 3412 build_always_stale: true) 3413genh += qemu_version 3414 3415hxdep = [] 3416hx_headers = [ 3417 ['qemu-options.hx', 'qemu-options.def'], 3418 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3419] 3420if have_system 3421 hx_headers += [ 3422 ['hmp-commands.hx', 'hmp-commands.h'], 3423 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3424 ] 3425endif 3426foreach d : hx_headers 3427 hxdep += custom_target(d[1], 3428 input: files(d[0]), 3429 output: d[1], 3430 capture: true, 3431 command: [hxtool, '-h', '@INPUT0@']) 3432endforeach 3433genh += hxdep 3434 3435############### 3436# Trace files # 3437############### 3438 3439# TODO: add each directory to the subdirs from its own meson.build, once 3440# we have those 3441trace_events_subdirs = [ 3442 'crypto', 3443 'qapi', 3444 'qom', 3445 'monitor', 3446 'util', 3447 'gdbstub', 3448] 3449if have_linux_user 3450 trace_events_subdirs += [ 'linux-user' ] 3451endif 3452if have_bsd_user 3453 trace_events_subdirs += [ 'bsd-user' ] 3454endif 3455if have_block 3456 trace_events_subdirs += [ 3457 'authz', 3458 'block', 3459 'chardev', 3460 'io', 3461 'nbd', 3462 'scsi', 3463 ] 3464endif 3465if have_system 3466 trace_events_subdirs += [ 3467 'accel/kvm', 3468 'audio', 3469 'backends', 3470 'backends/tpm', 3471 'ebpf', 3472 'hw/9pfs', 3473 'hw/acpi', 3474 'hw/adc', 3475 'hw/alpha', 3476 'hw/arm', 3477 'hw/audio', 3478 'hw/block', 3479 'hw/char', 3480 'hw/display', 3481 'hw/dma', 3482 'hw/fsi', 3483 'hw/hyperv', 3484 'hw/i2c', 3485 'hw/i386', 3486 'hw/i386/xen', 3487 'hw/i386/kvm', 3488 'hw/ide', 3489 'hw/input', 3490 'hw/intc', 3491 'hw/isa', 3492 'hw/mem', 3493 'hw/mips', 3494 'hw/misc', 3495 'hw/misc/macio', 3496 'hw/net', 3497 'hw/net/can', 3498 'hw/nubus', 3499 'hw/nvme', 3500 'hw/nvram', 3501 'hw/pci', 3502 'hw/pci-host', 3503 'hw/ppc', 3504 'hw/rtc', 3505 'hw/riscv', 3506 'hw/s390x', 3507 'hw/scsi', 3508 'hw/sd', 3509 'hw/sh4', 3510 'hw/sparc', 3511 'hw/sparc64', 3512 'hw/ssi', 3513 'hw/timer', 3514 'hw/tpm', 3515 'hw/ufs', 3516 'hw/usb', 3517 'hw/vfio', 3518 'hw/virtio', 3519 'hw/watchdog', 3520 'hw/xen', 3521 'hw/gpio', 3522 'migration', 3523 'net', 3524 'system', 3525 'ui', 3526 'hw/remote', 3527 ] 3528endif 3529if have_system or have_user 3530 trace_events_subdirs += [ 3531 'accel/tcg', 3532 'hw/core', 3533 'target/arm', 3534 'target/arm/hvf', 3535 'target/hppa', 3536 'target/i386', 3537 'target/i386/kvm', 3538 'target/loongarch', 3539 'target/mips/tcg', 3540 'target/ppc', 3541 'target/riscv', 3542 'target/s390x', 3543 'target/s390x/kvm', 3544 'target/sparc', 3545 ] 3546endif 3547 3548################### 3549# Collect sources # 3550################### 3551 3552authz_ss = ss.source_set() 3553blockdev_ss = ss.source_set() 3554block_ss = ss.source_set() 3555chardev_ss = ss.source_set() 3556common_ss = ss.source_set() 3557crypto_ss = ss.source_set() 3558hwcore_ss = ss.source_set() 3559io_ss = ss.source_set() 3560qmp_ss = ss.source_set() 3561qom_ss = ss.source_set() 3562system_ss = ss.source_set() 3563specific_fuzz_ss = ss.source_set() 3564specific_ss = ss.source_set() 3565rust_devices_ss = ss.source_set() 3566stub_ss = ss.source_set() 3567trace_ss = ss.source_set() 3568user_ss = ss.source_set() 3569util_ss = ss.source_set() 3570 3571# accel modules 3572qtest_module_ss = ss.source_set() 3573tcg_module_ss = ss.source_set() 3574 3575modules = {} 3576target_modules = {} 3577hw_arch = {} 3578target_arch = {} 3579target_system_arch = {} 3580target_user_arch = {} 3581 3582# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3583# that is filled in by qapi/. 3584subdir('qapi') 3585subdir('qobject') 3586subdir('stubs') 3587subdir('trace') 3588subdir('util') 3589subdir('qom') 3590subdir('authz') 3591subdir('crypto') 3592subdir('ui') 3593subdir('gdbstub') 3594if have_system 3595 subdir('hw') 3596else 3597 subdir('hw/core') 3598endif 3599 3600if enable_modules 3601 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3602 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3603endif 3604 3605qom_ss = qom_ss.apply({}) 3606libqom = static_library('qom', qom_ss.sources() + genh, 3607 dependencies: [qom_ss.dependencies()], 3608 build_by_default: false) 3609qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3610 dependencies: qom_ss.dependencies()) 3611 3612event_loop_base = files('event-loop-base.c') 3613event_loop_base = static_library('event-loop-base', 3614 sources: event_loop_base + genh, 3615 build_by_default: false) 3616event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3617 dependencies: [qom]) 3618 3619stub_ss = stub_ss.apply({}) 3620 3621util_ss.add_all(trace_ss) 3622util_ss = util_ss.apply({}) 3623libqemuutil = static_library('qemuutil', 3624 build_by_default: false, 3625 sources: util_ss.sources() + stub_ss.sources() + genh, 3626 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3627qemuutil = declare_dependency(link_with: libqemuutil, 3628 sources: genh + version_res, 3629 dependencies: [event_loop_base]) 3630 3631if have_system or have_user 3632 decodetree = generator(find_program('scripts/decodetree.py'), 3633 output: 'decode-@BASENAME@.c.inc', 3634 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3635 subdir('libdecnumber') 3636 subdir('target') 3637endif 3638 3639subdir('audio') 3640subdir('io') 3641subdir('chardev') 3642subdir('fsdev') 3643subdir('dump') 3644 3645if have_block 3646 block_ss.add(files( 3647 'block.c', 3648 'blockjob.c', 3649 'job.c', 3650 'qemu-io-cmds.c', 3651 )) 3652 if config_host_data.get('CONFIG_REPLICATION') 3653 block_ss.add(files('replication.c')) 3654 endif 3655 3656 subdir('nbd') 3657 subdir('scsi') 3658 subdir('block') 3659 3660 blockdev_ss.add(files( 3661 'blockdev.c', 3662 'blockdev-nbd.c', 3663 'iothread.c', 3664 'job-qmp.c', 3665 )) 3666 3667 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3668 # os-win32.c does not 3669 if host_os == 'windows' 3670 system_ss.add(files('os-win32.c')) 3671 else 3672 blockdev_ss.add(files('os-posix.c')) 3673 endif 3674endif 3675 3676common_ss.add(files('cpu-common.c')) 3677specific_ss.add(files('cpu-target.c')) 3678 3679subdir('system') 3680 3681# Work around a gcc bug/misfeature wherein constant propagation looks 3682# through an alias: 3683# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3684# to guess that a const variable is always zero. Without lto, this is 3685# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3686# without lto, not even the alias is required -- we simply use different 3687# declarations in different compilation units. 3688pagevary = files('page-vary-common.c') 3689if get_option('b_lto') 3690 pagevary_flags = ['-fno-lto'] 3691 if get_option('cfi') 3692 pagevary_flags += '-fno-sanitize=cfi-icall' 3693 endif 3694 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3695 c_args: pagevary_flags) 3696 pagevary = declare_dependency(link_with: pagevary) 3697endif 3698common_ss.add(pagevary) 3699specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3700 3701subdir('backends') 3702subdir('disas') 3703subdir('migration') 3704subdir('monitor') 3705subdir('net') 3706subdir('replay') 3707subdir('semihosting') 3708subdir('stats') 3709subdir('tcg') 3710subdir('fpu') 3711subdir('accel') 3712subdir('plugins') 3713subdir('ebpf') 3714 3715common_user_inc = [] 3716 3717subdir('common-user') 3718subdir('bsd-user') 3719subdir('linux-user') 3720 3721# needed for fuzzing binaries 3722subdir('tests/qtest/libqos') 3723subdir('tests/qtest/fuzz') 3724 3725# accel modules 3726tcg_real_module_ss = ss.source_set() 3727tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3728specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3729target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3730 'tcg': tcg_real_module_ss }} 3731 3732############################################## 3733# Internal static_libraries and dependencies # 3734############################################## 3735 3736modinfo_collect = find_program('scripts/modinfo-collect.py') 3737modinfo_generate = find_program('scripts/modinfo-generate.py') 3738modinfo_files = [] 3739 3740block_mods = [] 3741system_mods = [] 3742emulator_modules = [] 3743foreach d, list : modules 3744 if not (d == 'block' ? have_block : have_system) 3745 continue 3746 endif 3747 3748 foreach m, module_ss : list 3749 if enable_modules 3750 module_ss.add(modulecommon) 3751 module_ss = module_ss.apply(config_all_devices, strict: false) 3752 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3753 dependencies: module_ss.dependencies(), pic: true) 3754 if d == 'block' 3755 block_mods += sl 3756 else 3757 system_mods += sl 3758 endif 3759 emulator_modules += shared_module(sl.name(), 3760 name_prefix: '', 3761 objects: sl.extract_all_objects(recursive: false), 3762 dependencies: module_ss.dependencies(), 3763 install: true, 3764 install_dir: qemu_moddir) 3765 if module_ss.sources() != [] 3766 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3767 # input. Sources can be used multiple times but objects are 3768 # unique when it comes to lookup in compile_commands.json. 3769 # Depnds on a mesion version with 3770 # https://github.com/mesonbuild/meson/pull/8900 3771 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3772 output: d + '-' + m + '.modinfo', 3773 input: module_ss.sources() + genh, 3774 capture: true, 3775 command: [modinfo_collect, module_ss.sources()]) 3776 endif 3777 else 3778 if d == 'block' 3779 block_ss.add_all(module_ss) 3780 else 3781 system_ss.add_all(module_ss) 3782 endif 3783 endif 3784 endforeach 3785endforeach 3786 3787foreach d, list : target_modules 3788 foreach m, module_ss : list 3789 if enable_modules 3790 module_ss.add(modulecommon) 3791 foreach target : target_dirs 3792 if target.endswith('-softmmu') 3793 config_target = config_target_mak[target] 3794 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3795 c_args = ['-DCOMPILING_PER_TARGET', 3796 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3797 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3798 target_module_ss = module_ss.apply(config_target, strict: false) 3799 if target_module_ss.sources() != [] 3800 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3801 sl = static_library(module_name, 3802 [genh, target_module_ss.sources()], 3803 dependencies: target_module_ss.dependencies(), 3804 include_directories: target_inc, 3805 c_args: c_args, 3806 pic: true) 3807 system_mods += sl 3808 emulator_modules += shared_module(sl.name(), 3809 name_prefix: '', 3810 objects: sl.extract_all_objects(recursive: false), 3811 dependencies: target_module_ss.dependencies(), 3812 install: true, 3813 install_dir: qemu_moddir) 3814 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3815 modinfo_files += custom_target(module_name + '.modinfo', 3816 output: module_name + '.modinfo', 3817 input: target_module_ss.sources() + genh, 3818 capture: true, 3819 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3820 endif 3821 endif 3822 endforeach 3823 else 3824 specific_ss.add_all(module_ss) 3825 endif 3826 endforeach 3827endforeach 3828 3829if enable_modules 3830 foreach target : target_dirs 3831 if target.endswith('-softmmu') 3832 config_target = config_target_mak[target] 3833 config_devices_mak = target + '-config-devices.mak' 3834 modinfo_src = custom_target('modinfo-' + target + '.c', 3835 output: 'modinfo-' + target + '.c', 3836 input: modinfo_files, 3837 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3838 capture: true) 3839 3840 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3841 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3842 3843 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3844 hw_arch[arch].add(modinfo_dep) 3845 endif 3846 endforeach 3847 3848 if emulator_modules.length() > 0 3849 alias_target('modules', emulator_modules) 3850 endif 3851endif 3852 3853nm = find_program('nm') 3854undefsym = find_program('scripts/undefsym.py') 3855block_syms = custom_target('block.syms', output: 'block.syms', 3856 input: [libqemuutil, block_mods], 3857 capture: true, 3858 command: [undefsym, nm, '@INPUT@']) 3859qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3860 input: [libqemuutil, system_mods], 3861 capture: true, 3862 command: [undefsym, nm, '@INPUT@']) 3863 3864authz_ss = authz_ss.apply({}) 3865libauthz = static_library('authz', authz_ss.sources() + genh, 3866 dependencies: [authz_ss.dependencies()], 3867 build_by_default: false) 3868 3869authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 3870 dependencies: [authz_ss.dependencies(), qom]) 3871 3872crypto_ss = crypto_ss.apply({}) 3873libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3874 dependencies: [crypto_ss.dependencies()], 3875 build_by_default: false) 3876 3877crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 3878 dependencies: [crypto_ss.dependencies(), authz, qom]) 3879 3880io_ss = io_ss.apply({}) 3881libio = static_library('io', io_ss.sources() + genh, 3882 dependencies: [io_ss.dependencies()], 3883 link_with: libqemuutil, 3884 build_by_default: false) 3885 3886io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 3887 dependencies: [io_ss.dependencies(), crypto, qom]) 3888 3889libmigration = static_library('migration', sources: migration_files + genh, 3890 build_by_default: false) 3891migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 3892 dependencies: [qom, io]) 3893system_ss.add(migration) 3894 3895block_ss = block_ss.apply({}) 3896libblock = static_library('block', block_ss.sources() + genh, 3897 dependencies: block_ss.dependencies(), 3898 build_by_default: false) 3899 3900block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 3901 dependencies: [block_ss.dependencies(), crypto, io]) 3902 3903blockdev_ss = blockdev_ss.apply({}) 3904libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3905 dependencies: blockdev_ss.dependencies(), 3906 build_by_default: false) 3907 3908blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 3909 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 3910 3911qmp_ss = qmp_ss.apply({}) 3912libqmp = static_library('qmp', qmp_ss.sources() + genh, 3913 dependencies: qmp_ss.dependencies(), 3914 build_by_default: false) 3915 3916qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 3917 dependencies: qmp_ss.dependencies()) 3918 3919libchardev = static_library('chardev', chardev_ss.sources() + genh, 3920 dependencies: chardev_ss.dependencies(), 3921 build_by_default: false) 3922 3923chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 3924 dependencies: chardev_ss.dependencies()) 3925 3926hwcore_ss = hwcore_ss.apply({}) 3927libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3928 build_by_default: false) 3929hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 3930common_ss.add(hwcore) 3931 3932########### 3933# Targets # 3934########### 3935 3936system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3937common_ss.add(qom, qemuutil) 3938 3939common_ss.add_all(when: 'CONFIG_SYSTEM_ONLY', if_true: [system_ss]) 3940common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3941 3942# Note that this library is never used directly (only through extract_objects) 3943# and is not built by default; therefore, source files not used by the build 3944# configuration will be in build.ninja, but are never built by default. 3945common_all = static_library('common', 3946 build_by_default: false, 3947 sources: common_ss.all_sources() + genh, 3948 include_directories: common_user_inc, 3949 implicit_include_directories: false, 3950 dependencies: common_ss.all_dependencies()) 3951 3952if have_rust and have_system 3953 bindgen_args = [ 3954 '--disable-header-comment', 3955 '--raw-line', '// @generated', 3956 '--ctypes-prefix', 'std::os::raw', 3957 '--formatter', 'rustfmt', 3958 '--generate-block', 3959 '--generate-cstr', 3960 '--impl-debug', 3961 '--merge-extern-blocks', 3962 '--no-doc-comments', 3963 '--with-derive-default', 3964 '--no-layout-tests', 3965 '--no-prepend-enum-name', 3966 '--allowlist-file', meson.project_source_root() + '/include/.*', 3967 '--allowlist-file', meson.project_source_root() + '/.*', 3968 '--allowlist-file', meson.project_build_root() + '/.*' 3969 ] 3970 c_enums = [ 3971 'DeviceCategory', 3972 'GpioPolarity', 3973 'MachineInitPhase', 3974 'MemoryDeviceInfoKind', 3975 'MigrationPolicy', 3976 'MigrationPriority', 3977 'QEMUChrEvent', 3978 'QEMUClockType', 3979 'device_endian', 3980 'module_init_type', 3981 ] 3982 foreach enum : c_enums 3983 bindgen_args += ['--rustified-enum', enum] 3984 endforeach 3985 c_bitfields = [ 3986 'ClockEvent', 3987 'VMStateFlags', 3988 ] 3989 foreach enum : c_bitfields 3990 bindgen_args += ['--bitfield-enum', enum] 3991 endforeach 3992 3993 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 3994 # 3995 # Rust bindings generation with `bindgen` might fail in some cases where the 3996 # detected `libclang` does not match the expected `clang` version/target. In 3997 # this case you must pass the path to `clang` and `libclang` to your build 3998 # command invocation using the environment variables CLANG_PATH and 3999 # LIBCLANG_PATH 4000 bindings_rs = rust.bindgen( 4001 input: 'rust/wrapper.h', 4002 dependencies: common_ss.all_dependencies(), 4003 output: 'bindings.rs', 4004 include_directories: include_directories('.', 'include'), 4005 bindgen_version: ['>=0.69.4'], 4006 args: bindgen_args, 4007 ) 4008 subdir('rust') 4009endif 4010 4011 4012feature_to_c = find_program('scripts/feature_to_c.py') 4013rust_root_crate = find_program('scripts/rust/rust_root_crate.sh') 4014 4015if host_os == 'darwin' 4016 entitlement = find_program('scripts/entitlement.sh') 4017endif 4018 4019traceable = [] 4020emulators = {} 4021foreach target : target_dirs 4022 config_target = config_target_mak[target] 4023 target_name = config_target['TARGET_NAME'] 4024 target_base_arch = config_target['TARGET_BASE_ARCH'] 4025 arch_srcs = [config_target_h[target]] 4026 arch_deps = [] 4027 c_args = ['-DCOMPILING_PER_TARGET', 4028 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4029 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4030 link_args = emulator_link_args 4031 4032 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4033 if host_os == 'linux' 4034 target_inc += include_directories('linux-headers', is_system: true) 4035 endif 4036 if target.endswith('-softmmu') 4037 target_type='system' 4038 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4039 arch_srcs += t.sources() 4040 arch_deps += t.dependencies() 4041 4042 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4043 if hw_arch.has_key(hw_dir) 4044 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4045 arch_srcs += hw.sources() 4046 arch_deps += hw.dependencies() 4047 endif 4048 4049 arch_srcs += config_devices_h[target] 4050 link_args += ['@block.syms', '@qemu.syms'] 4051 else 4052 abi = config_target['TARGET_ABI_DIR'] 4053 target_type='user' 4054 target_inc += common_user_inc 4055 if target_base_arch in target_user_arch 4056 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4057 arch_srcs += t.sources() 4058 arch_deps += t.dependencies() 4059 endif 4060 if 'CONFIG_LINUX_USER' in config_target 4061 base_dir = 'linux-user' 4062 endif 4063 if 'CONFIG_BSD_USER' in config_target 4064 base_dir = 'bsd-user' 4065 target_inc += include_directories('bsd-user/' / host_os) 4066 target_inc += include_directories('bsd-user/host/' / host_arch) 4067 dir = base_dir / abi 4068 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4069 endif 4070 target_inc += include_directories( 4071 base_dir, 4072 base_dir / abi, 4073 ) 4074 if 'CONFIG_LINUX_USER' in config_target 4075 dir = base_dir / abi 4076 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4077 if config_target.has_key('TARGET_SYSTBL_ABI') 4078 arch_srcs += \ 4079 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4080 extra_args : config_target['TARGET_SYSTBL_ABI']) 4081 endif 4082 endif 4083 endif 4084 4085 if 'TARGET_XML_FILES' in config_target 4086 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4087 output: target + '-gdbstub-xml.c', 4088 input: files(config_target['TARGET_XML_FILES'].split()), 4089 command: [feature_to_c, '@INPUT@'], 4090 capture: true) 4091 arch_srcs += gdbstub_xml 4092 endif 4093 4094 t = target_arch[target_base_arch].apply(config_target, strict: false) 4095 arch_srcs += t.sources() 4096 arch_deps += t.dependencies() 4097 4098 target_common = common_ss.apply(config_target, strict: false) 4099 objects = common_all.extract_objects(target_common.sources()) 4100 arch_deps += target_common.dependencies() 4101 4102 target_specific = specific_ss.apply(config_target, strict: false) 4103 arch_srcs += target_specific.sources() 4104 arch_deps += target_specific.dependencies() 4105 4106 if have_rust and have_system 4107 target_rust = rust_devices_ss.apply(config_target, strict: false) 4108 crates = [] 4109 foreach dep : target_rust.dependencies() 4110 crates += dep.get_variable('crate') 4111 endforeach 4112 if crates.length() > 0 4113 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4114 output: 'rust_' + target.underscorify() + '.rs', 4115 command: [rust_root_crate, crates], 4116 capture: true, 4117 build_by_default: true, 4118 build_always_stale: true) 4119 rlib = static_library('rust_' + target.underscorify(), 4120 rlib_rs, 4121 dependencies: target_rust.dependencies(), 4122 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4123 rust_abi: 'c') 4124 arch_deps += declare_dependency(link_whole: [rlib]) 4125 endif 4126 endif 4127 4128 # allow using headers from the dependencies but do not include the sources, 4129 # because this emulator only needs those in "objects". For external 4130 # dependencies, the full dependency is included below in the executable. 4131 lib_deps = [] 4132 foreach dep : arch_deps 4133 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4134 endforeach 4135 4136 lib = static_library('qemu-' + target, 4137 sources: arch_srcs + genh, 4138 dependencies: lib_deps, 4139 objects: objects, 4140 include_directories: target_inc, 4141 c_args: c_args, 4142 build_by_default: false) 4143 4144 if target.endswith('-softmmu') 4145 execs = [{ 4146 'name': 'qemu-system-' + target_name, 4147 'win_subsystem': 'console', 4148 'sources': files('system/main.c'), 4149 'dependencies': [] 4150 }] 4151 if host_os == 'windows' and (sdl.found() or gtk.found()) 4152 execs += [{ 4153 'name': 'qemu-system-' + target_name + 'w', 4154 'win_subsystem': 'windows', 4155 'sources': files('system/main.c'), 4156 'dependencies': [] 4157 }] 4158 endif 4159 if get_option('fuzzing') 4160 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4161 execs += [{ 4162 'name': 'qemu-fuzz-' + target_name, 4163 'win_subsystem': 'console', 4164 'sources': specific_fuzz.sources(), 4165 'dependencies': specific_fuzz.dependencies(), 4166 }] 4167 endif 4168 else 4169 execs = [{ 4170 'name': 'qemu-' + target_name, 4171 'win_subsystem': 'console', 4172 'sources': [], 4173 'dependencies': [] 4174 }] 4175 endif 4176 foreach exe: execs 4177 exe_name = exe['name'] 4178 if host_os == 'darwin' 4179 exe_name += '-unsigned' 4180 endif 4181 4182 emulator = executable(exe_name, exe['sources'], 4183 install: true, 4184 c_args: c_args, 4185 dependencies: arch_deps + exe['dependencies'], 4186 objects: lib.extract_all_objects(recursive: true), 4187 link_depends: [block_syms, qemu_syms], 4188 link_args: link_args, 4189 win_subsystem: exe['win_subsystem']) 4190 4191 if host_os == 'darwin' 4192 icon = 'pc-bios/qemu.rsrc' 4193 build_input = [emulator, files(icon)] 4194 install_input = [ 4195 get_option('bindir') / exe_name, 4196 meson.current_source_dir() / icon 4197 ] 4198 if 'CONFIG_HVF' in config_target 4199 entitlements = 'accel/hvf/entitlements.plist' 4200 build_input += files(entitlements) 4201 install_input += meson.current_source_dir() / entitlements 4202 endif 4203 4204 emulators += {exe['name'] : custom_target(exe['name'], 4205 input: build_input, 4206 output: exe['name'], 4207 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4208 } 4209 4210 meson.add_install_script(entitlement, '--install', 4211 get_option('bindir') / exe['name'], 4212 install_input) 4213 else 4214 emulators += {exe['name']: emulator} 4215 endif 4216 4217 traceable += [{ 4218 'exe': exe['name'], 4219 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4220 }] 4221 4222 endforeach 4223endforeach 4224 4225# Other build targets 4226 4227if get_option('plugins') 4228 install_headers('include/qemu/qemu-plugin.h') 4229 if host_os == 'windows' 4230 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4231 # so that plugin authors can compile against it. 4232 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4233 endif 4234endif 4235 4236subdir('qga') 4237 4238# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4239# when we don't build tools or system 4240if xkbcommon.found() 4241 # used for the update-keymaps target, so include rules even if !have_tools 4242 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4243 dependencies: [qemuutil, xkbcommon], install: have_tools) 4244endif 4245 4246if have_tools 4247 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4248 link_args: '@block.syms', link_depends: block_syms, 4249 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4250 qemu_io = executable('qemu-io', files('qemu-io.c'), 4251 link_args: '@block.syms', link_depends: block_syms, 4252 dependencies: [block, qemuutil], install: true) 4253 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4254 link_args: '@block.syms', link_depends: block_syms, 4255 dependencies: [blockdev, qemuutil, selinux], 4256 install: true) 4257 4258 subdir('storage-daemon') 4259 4260 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4261 traceable += [{ 4262 'exe': exe, 4263 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4264 }] 4265 endforeach 4266 4267 subdir('contrib/elf2dmp') 4268 4269 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4270 dependencies: qemuutil, 4271 install: true) 4272 4273 if have_vhost_user 4274 subdir('contrib/vhost-user-blk') 4275 subdir('contrib/vhost-user-gpu') 4276 subdir('contrib/vhost-user-input') 4277 subdir('contrib/vhost-user-scsi') 4278 endif 4279 4280 if host_os == 'linux' 4281 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4282 dependencies: [qemuutil, libcap_ng], 4283 install: true, 4284 install_dir: get_option('libexecdir')) 4285 4286 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4287 dependencies: [authz, crypto, io, qom, qemuutil, 4288 libcap_ng, mpathpersist], 4289 install: true) 4290 4291 if cpu in ['x86', 'x86_64'] 4292 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4293 dependencies: [authz, crypto, io, qom, qemuutil, 4294 libcap_ng, mpathpersist], 4295 install: true) 4296 endif 4297 endif 4298 4299 if have_ivshmem 4300 subdir('contrib/ivshmem-client') 4301 subdir('contrib/ivshmem-server') 4302 endif 4303endif 4304 4305if stap.found() 4306 foreach t: traceable 4307 foreach stp: [ 4308 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4309 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4310 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4311 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4312 ] 4313 cmd = [ 4314 tracetool, '--group=all', '--format=' + stp['fmt'], 4315 '--binary=' + stp['bin'], 4316 '--probe-prefix=' + t['probe-prefix'], 4317 '@INPUT@', '@OUTPUT@' 4318 ] 4319 4320 custom_target(t['exe'] + stp['ext'], 4321 input: trace_events_all, 4322 output: t['exe'] + stp['ext'], 4323 install: stp['install'], 4324 install_dir: get_option('datadir') / 'systemtap/tapset', 4325 command: cmd, 4326 depend_files: tracetool_depends) 4327 endforeach 4328 endforeach 4329endif 4330 4331subdir('scripts') 4332subdir('tools') 4333subdir('pc-bios') 4334subdir('docs') 4335subdir('tests') 4336if gtk.found() 4337 subdir('po') 4338endif 4339 4340if host_machine.system() == 'windows' 4341 nsis_cmd = [ 4342 find_program('scripts/nsis.py'), 4343 '@OUTPUT@', 4344 get_option('prefix'), 4345 meson.current_source_dir(), 4346 glib_pc.get_variable('bindir'), 4347 host_machine.cpu(), 4348 '--', 4349 '-DDISPLAYVERSION=' + meson.project_version(), 4350 ] 4351 if build_docs 4352 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4353 endif 4354 if gtk.found() 4355 nsis_cmd += '-DCONFIG_GTK=y' 4356 endif 4357 4358 nsis = custom_target('nsis', 4359 output: 'qemu-setup-' + meson.project_version() + '.exe', 4360 input: files('qemu.nsi'), 4361 build_always_stale: true, 4362 command: nsis_cmd + ['@INPUT@']) 4363 alias_target('installer', nsis) 4364endif 4365 4366######################### 4367# Configuration summary # 4368######################### 4369 4370# Build environment 4371summary_info = {} 4372summary_info += {'Build directory': meson.current_build_dir()} 4373summary_info += {'Source path': meson.current_source_dir()} 4374summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4375summary(summary_info, bool_yn: true, section: 'Build environment') 4376 4377# Directories 4378summary_info += {'Install prefix': get_option('prefix')} 4379summary_info += {'BIOS directory': qemu_datadir} 4380pathsep = host_os == 'windows' ? ';' : ':' 4381summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4382summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4383summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4384summary_info += {'module directory': qemu_moddir} 4385summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4386summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4387summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4388if host_os != 'windows' 4389 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4390 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4391else 4392 summary_info += {'local state directory': 'queried at runtime'} 4393endif 4394summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4395summary(summary_info, bool_yn: true, section: 'Directories') 4396 4397# Host binaries 4398summary_info = {} 4399summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4400summary_info += {'sphinx-build': sphinx_build} 4401 4402# FIXME: the [binaries] section of machine files, which can be probed 4403# with find_program(), would be great for passing gdb and genisoimage 4404# paths from configure to Meson. However, there seems to be no way to 4405# hide a program (for example if gdb is too old). 4406if config_host.has_key('GDB') 4407 summary_info += {'gdb': config_host['GDB']} 4408endif 4409summary_info += {'iasl': iasl} 4410summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4411if host_os == 'windows' and have_ga 4412 summary_info += {'wixl': wixl} 4413endif 4414if slirp.found() and have_system 4415 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4416endif 4417summary(summary_info, bool_yn: true, section: 'Host binaries') 4418 4419# Configurable features 4420summary_info = {} 4421summary_info += {'Documentation': build_docs} 4422summary_info += {'system-mode emulation': have_system} 4423summary_info += {'user-mode emulation': have_user} 4424summary_info += {'block layer': have_block} 4425summary_info += {'Install blobs': get_option('install_blobs')} 4426summary_info += {'module support': enable_modules} 4427if enable_modules 4428 summary_info += {'alternative module path': get_option('module_upgrades')} 4429endif 4430summary_info += {'fuzzing support': get_option('fuzzing')} 4431if have_system 4432 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4433endif 4434summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4435if 'simple' in get_option('trace_backends') 4436 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4437endif 4438summary_info += {'D-Bus display': dbus_display} 4439summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4440summary_info += {'Relocatable install': get_option('relocatable')} 4441summary_info += {'vhost-kernel support': have_vhost_kernel} 4442summary_info += {'vhost-net support': have_vhost_net} 4443summary_info += {'vhost-user support': have_vhost_user} 4444summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4445summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4446summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4447summary_info += {'build guest agent': have_ga} 4448summary(summary_info, bool_yn: true, section: 'Configurable features') 4449 4450# Compilation information 4451summary_info = {} 4452summary_info += {'host CPU': cpu} 4453summary_info += {'host endianness': build_machine.endian()} 4454summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4455summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4456if 'cpp' in all_languages 4457 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4458else 4459 summary_info += {'C++ compiler': false} 4460endif 4461if 'objc' in all_languages 4462 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4463else 4464 summary_info += {'Objective-C compiler': false} 4465endif 4466summary_info += {'Rust support': have_rust} 4467if have_rust 4468 summary_info += {'rustc version': rustc.version()} 4469 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4470 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4471endif 4472option_cflags = (get_option('debug') ? ['-g'] : []) 4473if get_option('optimization') != 'plain' 4474 option_cflags += ['-O' + get_option('optimization')] 4475endif 4476summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4477if 'cpp' in all_languages 4478 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4479endif 4480if 'objc' in all_languages 4481 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4482endif 4483link_args = get_option('c_link_args') 4484if link_args.length() > 0 4485 summary_info += {'LDFLAGS': ' '.join(link_args)} 4486endif 4487summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4488if 'cpp' in all_languages 4489 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4490endif 4491if 'objc' in all_languages 4492 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4493endif 4494summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4495summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4496summary_info += {'PIE': get_option('b_pie')} 4497summary_info += {'static build': get_option('prefer_static')} 4498summary_info += {'malloc trim support': has_malloc_trim} 4499summary_info += {'membarrier': have_membarrier} 4500summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4501summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4502summary_info += {'mutex debugging': get_option('debug_mutex')} 4503summary_info += {'memory allocator': get_option('malloc')} 4504summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4505summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4506summary_info += {'gcov': get_option('b_coverage')} 4507summary_info += {'thread sanitizer': get_option('tsan')} 4508summary_info += {'CFI support': get_option('cfi')} 4509if get_option('cfi') 4510 summary_info += {'CFI debug support': get_option('cfi_debug')} 4511endif 4512summary_info += {'strip binaries': get_option('strip')} 4513summary_info += {'sparse': sparse} 4514summary_info += {'mingw32 support': host_os == 'windows'} 4515summary(summary_info, bool_yn: true, section: 'Compilation') 4516 4517# snarf the cross-compilation information for tests 4518summary_info = {} 4519have_cross = false 4520foreach target: target_dirs 4521 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4522 if fs.exists(tcg_mak) 4523 config_cross_tcg = keyval.load(tcg_mak) 4524 if 'CC' in config_cross_tcg 4525 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4526 have_cross = true 4527 endif 4528 endif 4529endforeach 4530if have_cross 4531 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4532endif 4533 4534# Targets and accelerators 4535summary_info = {} 4536if have_system 4537 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4538 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4539 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4540 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4541 summary_info += {'Xen support': xen.found()} 4542 if xen.found() 4543 summary_info += {'xen ctrl version': xen.version()} 4544 endif 4545 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4546endif 4547summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4548if config_all_accel.has_key('CONFIG_TCG') 4549 if get_option('tcg_interpreter') 4550 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4551 else 4552 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4553 endif 4554 summary_info += {'TCG plugins': get_option('plugins')} 4555 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4556 if have_linux_user or have_bsd_user 4557 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4558 endif 4559endif 4560summary_info += {'target list': ' '.join(target_dirs)} 4561if have_system 4562 summary_info += {'default devices': get_option('default_devices')} 4563 summary_info += {'out of process emulation': multiprocess_allowed} 4564 summary_info += {'vfio-user server': vfio_user_server_allowed} 4565endif 4566summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4567 4568# Block layer 4569summary_info = {} 4570summary_info += {'coroutine backend': coroutine_backend} 4571summary_info += {'coroutine pool': have_coroutine_pool} 4572if have_block 4573 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4574 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4575 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4576 summary_info += {'VirtFS (9P) support': have_virtfs} 4577 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4578 summary_info += {'bochs support': get_option('bochs').allowed()} 4579 summary_info += {'cloop support': get_option('cloop').allowed()} 4580 summary_info += {'dmg support': get_option('dmg').allowed()} 4581 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4582 summary_info += {'vdi support': get_option('vdi').allowed()} 4583 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4584 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4585 summary_info += {'vpc support': get_option('vpc').allowed()} 4586 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4587 summary_info += {'qed support': get_option('qed').allowed()} 4588 summary_info += {'parallels support': get_option('parallels').allowed()} 4589 summary_info += {'FUSE exports': fuse} 4590 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4591endif 4592summary(summary_info, bool_yn: true, section: 'Block layer support') 4593 4594# Crypto 4595summary_info = {} 4596summary_info += {'TLS priority': get_option('tls_priority')} 4597summary_info += {'GNUTLS support': gnutls} 4598if gnutls.found() 4599 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4600endif 4601summary_info += {'libgcrypt': gcrypt} 4602summary_info += {'nettle': nettle} 4603if nettle.found() 4604 summary_info += {' XTS': xts != 'private'} 4605endif 4606summary_info += {'SM4 ALG support': crypto_sm4} 4607summary_info += {'AF_ALG support': have_afalg} 4608summary_info += {'rng-none': get_option('rng_none')} 4609summary_info += {'Linux keyring': have_keyring} 4610summary_info += {'Linux keyutils': keyutils} 4611summary(summary_info, bool_yn: true, section: 'Crypto') 4612 4613# UI 4614summary_info = {} 4615if host_os == 'darwin' 4616 summary_info += {'Cocoa support': cocoa} 4617endif 4618summary_info += {'SDL support': sdl} 4619summary_info += {'SDL image support': sdl_image} 4620summary_info += {'GTK support': gtk} 4621summary_info += {'pixman': pixman} 4622summary_info += {'VTE support': vte} 4623summary_info += {'PNG support': png} 4624summary_info += {'VNC support': vnc} 4625if vnc.found() 4626 summary_info += {'VNC SASL support': sasl} 4627 summary_info += {'VNC JPEG support': jpeg} 4628endif 4629summary_info += {'spice protocol support': spice_protocol} 4630if spice_protocol.found() 4631 summary_info += {' spice server support': spice} 4632endif 4633summary_info += {'curses support': curses} 4634summary_info += {'brlapi support': brlapi} 4635summary(summary_info, bool_yn: true, section: 'User interface') 4636 4637# Graphics backends 4638summary_info = {} 4639summary_info += {'VirGL support': virgl} 4640summary_info += {'Rutabaga support': rutabaga} 4641summary(summary_info, bool_yn: true, section: 'Graphics backends') 4642 4643# Audio backends 4644summary_info = {} 4645if host_os not in ['darwin', 'haiku', 'windows'] 4646 summary_info += {'OSS support': oss} 4647 summary_info += {'sndio support': sndio} 4648elif host_os == 'darwin' 4649 summary_info += {'CoreAudio support': coreaudio} 4650elif host_os == 'windows' 4651 summary_info += {'DirectSound support': dsound} 4652endif 4653if host_os == 'linux' 4654 summary_info += {'ALSA support': alsa} 4655 summary_info += {'PulseAudio support': pulse} 4656endif 4657summary_info += {'PipeWire support': pipewire} 4658summary_info += {'JACK support': jack} 4659summary(summary_info, bool_yn: true, section: 'Audio backends') 4660 4661# Network backends 4662summary_info = {} 4663if host_os == 'darwin' 4664 summary_info += {'vmnet.framework support': vmnet} 4665endif 4666summary_info += {'AF_XDP support': libxdp} 4667summary_info += {'slirp support': slirp} 4668summary_info += {'vde support': vde} 4669summary_info += {'netmap support': have_netmap} 4670summary_info += {'l2tpv3 support': have_l2tpv3} 4671summary(summary_info, bool_yn: true, section: 'Network backends') 4672 4673# Libraries 4674summary_info = {} 4675summary_info += {'libtasn1': tasn1} 4676summary_info += {'PAM': pam} 4677summary_info += {'iconv support': iconv} 4678summary_info += {'blkio support': blkio} 4679summary_info += {'curl support': curl} 4680summary_info += {'Multipath support': mpathpersist} 4681summary_info += {'Linux AIO support': libaio} 4682summary_info += {'Linux io_uring support': linux_io_uring} 4683summary_info += {'ATTR/XATTR support': libattr} 4684summary_info += {'RDMA support': rdma} 4685summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4686summary_info += {'libcap-ng support': libcap_ng} 4687summary_info += {'bpf support': libbpf} 4688summary_info += {'rbd support': rbd} 4689summary_info += {'smartcard support': cacard} 4690summary_info += {'U2F support': u2f} 4691summary_info += {'libusb': libusb} 4692summary_info += {'usb net redir': usbredir} 4693summary_info += {'OpenGL support (epoxy)': opengl} 4694summary_info += {'GBM': gbm} 4695summary_info += {'libiscsi support': libiscsi} 4696summary_info += {'libnfs support': libnfs} 4697if host_os == 'windows' 4698 if have_ga 4699 summary_info += {'QGA VSS support': have_qga_vss} 4700 endif 4701endif 4702summary_info += {'seccomp support': seccomp} 4703summary_info += {'GlusterFS support': glusterfs} 4704summary_info += {'hv-balloon support': hv_balloon} 4705summary_info += {'TPM support': have_tpm} 4706summary_info += {'libssh support': libssh} 4707summary_info += {'lzo support': lzo} 4708summary_info += {'snappy support': snappy} 4709summary_info += {'bzip2 support': libbzip2} 4710summary_info += {'lzfse support': liblzfse} 4711summary_info += {'zstd support': zstd} 4712summary_info += {'Query Processing Library support': qpl} 4713summary_info += {'UADK Library support': uadk} 4714summary_info += {'qatzip support': qatzip} 4715summary_info += {'NUMA host support': numa} 4716summary_info += {'capstone': capstone} 4717summary_info += {'libpmem support': libpmem} 4718summary_info += {'libdaxctl support': libdaxctl} 4719summary_info += {'libcbor support': libcbor} 4720summary_info += {'libudev': libudev} 4721# Dummy dependency, keep .found() 4722summary_info += {'FUSE lseek': fuse_lseek.found()} 4723summary_info += {'selinux': selinux} 4724summary_info += {'libdw': libdw} 4725if host_os == 'freebsd' 4726 summary_info += {'libinotify-kqueue': inotify} 4727endif 4728summary(summary_info, bool_yn: true, section: 'Dependencies') 4729 4730if host_arch == 'unknown' 4731 message() 4732 warning('UNSUPPORTED HOST CPU') 4733 message() 4734 message('Support for CPU host architecture ' + cpu + ' is not currently') 4735 message('maintained. The QEMU project does not guarantee that QEMU will') 4736 message('compile or work on this host CPU. You can help by volunteering') 4737 message('to maintain it and providing a build host for our continuous') 4738 message('integration setup.') 4739 if get_option('tcg').allowed() and target_dirs.length() > 0 4740 message() 4741 message('configure has succeeded and you can continue to build, but') 4742 message('QEMU will use a slow interpreter to emulate the target CPU.') 4743 endif 4744elif host_arch == 'mips' 4745 message() 4746 warning('DEPRECATED HOST CPU') 4747 message() 4748 message('Support for CPU host architecture ' + cpu + ' is going to be') 4749 message('dropped as soon as the QEMU project stops supporting Debian 12') 4750 message('("Bookworm"). Going forward, the QEMU project will not guarantee') 4751 message('that QEMU will compile or work on this host CPU.') 4752endif 4753 4754if not supported_oses.contains(host_os) 4755 message() 4756 warning('UNSUPPORTED HOST OS') 4757 message() 4758 message('Support for host OS ' + host_os + 'is not currently maintained.') 4759 message('configure has succeeded and you can continue to build, but') 4760 message('the QEMU project does not guarantee that QEMU will compile or') 4761 message('work on this operating system. You can help by volunteering') 4762 message('to maintain it and providing a build host for our continuous') 4763 message('integration setup. This will ensure that future versions of QEMU') 4764 message('will keep working on ' + host_os + '.') 4765endif 4766 4767if host_arch == 'unknown' or not supported_oses.contains(host_os) 4768 message() 4769 message('If you want to help supporting QEMU on this platform, please') 4770 message('contact the developers at qemu-devel@nongnu.org.') 4771endif 4772 4773actually_reloc = get_option('relocatable') 4774# check if get_relocated_path() is actually able to relocate paths 4775if get_option('relocatable') and \ 4776 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 4777 message() 4778 warning('bindir not included within prefix, the installation will not be relocatable.') 4779 actually_reloc = false 4780endif 4781if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 4782 if host_os == 'windows' 4783 message() 4784 warning('Windows installs should usually be relocatable.') 4785 endif 4786 message() 4787 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 4788 message('Use --disable-relocatable to remove this warning.') 4789endif 4790