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