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 2763config_host_data.set('HAVE_TCP_KEEPCNT', 2764 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPCNT') or 2765 cc.compiles(''' 2766 #include <ws2tcpip.h> 2767 #ifndef TCP_KEEPCNT 2768 #error 2769 #endif 2770 int main(void) { return 0; }''', 2771 name: 'Win32 TCP_KEEPCNT')) 2772# On Darwin TCP_KEEPIDLE is available under different name, TCP_KEEPALIVE. 2773# https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/bsd/man/man4/tcp.4#L172 2774config_host_data.set('HAVE_TCP_KEEPIDLE', 2775 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE') or 2776 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPALIVE') or 2777 cc.compiles(''' 2778 #include <ws2tcpip.h> 2779 #ifndef TCP_KEEPIDLE 2780 #error 2781 #endif 2782 int main(void) { return 0; }''', 2783 name: 'Win32 TCP_KEEPIDLE')) 2784config_host_data.set('HAVE_TCP_KEEPINTVL', 2785 cc.has_header_symbol('netinet/tcp.h', 'TCP_KEEPINTVL') or 2786 cc.compiles(''' 2787 #include <ws2tcpip.h> 2788 #ifndef TCP_KEEPINTVL 2789 #error 2790 #endif 2791 int main(void) { return 0; }''', 2792 name: 'Win32 TCP_KEEPINTVL')) 2793 2794# has_member 2795config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 2796 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 2797 prefix: '#include <signal.h>')) 2798config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 2799 cc.has_member('struct stat', 'st_atim', 2800 prefix: '#include <sys/stat.h>')) 2801config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY', 2802 cc.has_member('struct blk_zone', 'capacity', 2803 prefix: '#include <linux/blkzoned.h>')) 2804 2805# has_type 2806config_host_data.set('CONFIG_IOVEC', 2807 cc.has_type('struct iovec', 2808 prefix: '#include <sys/uio.h>')) 2809config_host_data.set('HAVE_UTMPX', 2810 cc.has_type('struct utmpx', 2811 prefix: '#include <utmpx.h>')) 2812 2813config_host_data.set('CONFIG_EVENTFD', cc.links(''' 2814 #include <sys/eventfd.h> 2815 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 2816config_host_data.set('CONFIG_FDATASYNC', cc.links(osdep_prefix + ''' 2817 int main(void) { 2818 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 2819 return fdatasync(0); 2820 #else 2821 #error Not supported 2822 #endif 2823 }''')) 2824 2825has_madvise = cc.links(osdep_prefix + ''' 2826 #include <sys/mman.h> 2827 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 2828missing_madvise_proto = false 2829if has_madvise 2830 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 2831 # but forget to prototype it. In this case, has_madvise will be true (the 2832 # test program links despite a compile warning). To detect the 2833 # missing-prototype case, we try again with a definitely-bogus prototype. 2834 # This will only compile if the system headers don't provide the prototype; 2835 # otherwise the conflicting prototypes will cause a compiler error. 2836 missing_madvise_proto = cc.links(osdep_prefix + '''> 2837 #include <sys/mman.h> 2838 extern int madvise(int); 2839 int main(void) { return madvise(0); }''') 2840endif 2841config_host_data.set('CONFIG_MADVISE', has_madvise) 2842config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 2843 2844config_host_data.set('CONFIG_MEMFD', cc.links(osdep_prefix + ''' 2845 #include <sys/mman.h> 2846 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 2847config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(osdep_prefix + ''' 2848 #if !defined(AT_EMPTY_PATH) 2849 # error missing definition 2850 #else 2851 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 2852 #endif''')) 2853 2854# On Darwin posix_madvise() has the same return semantics as plain madvise(), 2855# i.e. errno is set and -1 is returned. That's not really how POSIX defines the 2856# function. On the flip side, it has madvise() which is preferred anyways. 2857if host_os != 'darwin' 2858 config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(osdep_prefix + ''' 2859 #include <sys/mman.h> 2860 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 2861endif 2862 2863config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(osdep_prefix + ''' 2864 #include <pthread.h> 2865 2866 static void *f(void *p) { return NULL; } 2867 int main(void) 2868 { 2869 pthread_t thread; 2870 pthread_create(&thread, 0, f, 0); 2871 pthread_setname_np(thread, "QEMU"); 2872 return 0; 2873 }''', dependencies: threads)) 2874config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(osdep_prefix + ''' 2875 #include <pthread.h> 2876 2877 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 2878 int main(void) 2879 { 2880 pthread_t thread; 2881 pthread_create(&thread, 0, f, 0); 2882 return 0; 2883 }''', dependencies: threads)) 2884config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(osdep_prefix + ''' 2885 #include <pthread.h> 2886 #include <pthread_np.h> 2887 2888 static void *f(void *p) { return NULL; } 2889 int main(void) 2890 { 2891 pthread_t thread; 2892 pthread_create(&thread, 0, f, 0); 2893 pthread_set_name_np(thread, "QEMU"); 2894 return 0; 2895 }''', dependencies: threads)) 2896config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(osdep_prefix + ''' 2897 #include <pthread.h> 2898 2899 int main(void) 2900 { 2901 pthread_condattr_t attr 2902 pthread_condattr_init(&attr); 2903 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 2904 return 0; 2905 }''', dependencies: threads)) 2906config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(osdep_prefix + ''' 2907 #include <pthread.h> 2908 2909 static void *f(void *p) { return NULL; } 2910 int main(void) 2911 { 2912 int setsize = CPU_ALLOC_SIZE(64); 2913 pthread_t thread; 2914 cpu_set_t *cpuset; 2915 pthread_create(&thread, 0, f, 0); 2916 cpuset = CPU_ALLOC(64); 2917 CPU_ZERO_S(setsize, cpuset); 2918 pthread_setaffinity_np(thread, setsize, cpuset); 2919 pthread_getaffinity_np(thread, setsize, cpuset); 2920 CPU_FREE(cpuset); 2921 return 0; 2922 }''', dependencies: threads)) 2923config_host_data.set('CONFIG_SIGNALFD', cc.links(osdep_prefix + ''' 2924 #include <sys/signalfd.h> 2925 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 2926config_host_data.set('CONFIG_SPLICE', cc.links(osdep_prefix + ''' 2927 int main(void) 2928 { 2929 int len, fd = 0; 2930 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 2931 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 2932 return 0; 2933 }''')) 2934 2935config_host_data.set('HAVE_MLOCKALL', cc.links(osdep_prefix + ''' 2936 #include <sys/mman.h> 2937 int main(void) { 2938 return mlockall(MCL_FUTURE); 2939 }''')) 2940 2941config_host_data.set('HAVE_MLOCK_ONFAULT', cc.links(osdep_prefix + ''' 2942 #include <sys/mman.h> 2943 int main(void) { 2944 return mlockall(MCL_FUTURE | MCL_ONFAULT); 2945 }''')) 2946 2947have_l2tpv3 = false 2948if get_option('l2tpv3').allowed() and have_system 2949 have_l2tpv3 = cc.has_type('struct mmsghdr', 2950 prefix: osdep_prefix + ''' 2951 #include <sys/socket.h> 2952 #include <linux/ip.h>''') 2953endif 2954config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2955 2956have_netmap = false 2957if get_option('netmap').allowed() and have_system 2958 have_netmap = cc.compiles(''' 2959 #include <inttypes.h> 2960 #include <net/if.h> 2961 #include <net/netmap.h> 2962 #include <net/netmap_user.h> 2963 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2964 #error 2965 #endif 2966 int main(void) { return 0; }''') 2967 if not have_netmap and get_option('netmap').enabled() 2968 error('Netmap headers not available') 2969 endif 2970endif 2971config_host_data.set('CONFIG_NETMAP', have_netmap) 2972 2973# Work around a system header bug with some kernel/XFS header 2974# versions where they both try to define 'struct fsxattr': 2975# xfs headers will not try to redefine structs from linux headers 2976# if this macro is set. 2977config_host_data.set('HAVE_FSXATTR', cc.links(''' 2978 #include <linux/fs.h> 2979 struct fsxattr foo; 2980 int main(void) { 2981 return 0; 2982 }''')) 2983 2984# Some versions of Mac OS X incorrectly define SIZE_MAX 2985config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2986 #include <stdint.h> 2987 #include <stdio.h> 2988 int main(void) { 2989 return printf("%zu", SIZE_MAX); 2990 }''', args: ['-Werror'])) 2991 2992# See if 64-bit atomic operations are supported. 2993# Note that without __atomic builtins, we can only 2994# assume atomic loads/stores max at pointer size. 2995config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 2996 #include <stdint.h> 2997 int main(void) 2998 { 2999 uint64_t x = 0, y = 0; 3000 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 3001 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 3002 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 3003 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 3004 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 3005 return 0; 3006 }''', args: qemu_isa_flags)) 3007 3008# has_int128_type is set to false on Emscripten to avoid errors by libffi 3009# during runtime. 3010has_int128_type = host_os != 'emscripten' and cc.compiles(''' 3011 __int128_t a; 3012 __uint128_t b; 3013 int main(void) { b = a; }''') 3014config_host_data.set('CONFIG_INT128_TYPE', has_int128_type) 3015 3016has_int128 = has_int128_type and cc.links(''' 3017 __int128_t a; 3018 __uint128_t b; 3019 int main (void) { 3020 a = a + b; 3021 b = a * b; 3022 a = a * a; 3023 return 0; 3024 }''') 3025config_host_data.set('CONFIG_INT128', has_int128) 3026 3027if has_int128_type 3028 # "do we have 128-bit atomics which are handled inline and specifically not 3029 # via libatomic". The reason we can't use libatomic is documented in the 3030 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 3031 # We only care about these operations on 16-byte aligned pointers, so 3032 # force 16-byte alignment of the pointer, which may be greater than 3033 # __alignof(unsigned __int128) for the host. 3034 atomic_test_128 = ''' 3035 int main(int ac, char **av) { 3036 __uint128_t *p = __builtin_assume_aligned(av[ac - 1], 16); 3037 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED); 3038 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED); 3039 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 3040 return 0; 3041 }''' 3042 has_atomic128 = cc.links(atomic_test_128, args: qemu_isa_flags) 3043 3044 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 3045 3046 if not has_atomic128 3047 # Even with __builtin_assume_aligned, the above test may have failed 3048 # without optimization enabled. Try again with optimizations locally 3049 # enabled for the function. See 3050 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389 3051 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128, 3052 args: qemu_isa_flags) 3053 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt) 3054 3055 if not has_atomic128_opt 3056 config_host_data.set('CONFIG_CMPXCHG128', cc.links(''' 3057 int main(void) 3058 { 3059 __uint128_t x = 0, y = 0; 3060 __sync_val_compare_and_swap_16(&x, y, x); 3061 return 0; 3062 } 3063 ''', args: qemu_isa_flags)) 3064 endif 3065 endif 3066endif 3067 3068config_host_data.set('CONFIG_GETAUXVAL', cc.links(osdep_prefix + ''' 3069 #include <sys/auxv.h> 3070 int main(void) { 3071 return getauxval(AT_HWCAP) == 0; 3072 }''')) 3073 3074config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(osdep_prefix + ''' 3075 #include <sys/auxv.h> 3076 int main(void) { 3077 unsigned long hwcap = 0; 3078 elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); 3079 return hwcap; 3080 }''')) 3081 3082config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 3083 #include <linux/usbdevice_fs.h> 3084 3085 #ifndef USBDEVFS_GET_CAPABILITIES 3086 #error "USBDEVFS_GET_CAPABILITIES undefined" 3087 #endif 3088 3089 #ifndef USBDEVFS_DISCONNECT_CLAIM 3090 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 3091 #endif 3092 3093 int main(void) { return 0; }''')) 3094 3095have_keyring = get_option('keyring') \ 3096 .require(host_os == 'linux', error_message: 'keyring is only available on Linux') \ 3097 .require(cc.compiles(''' 3098 #include <errno.h> 3099 #include <asm/unistd.h> 3100 #include <linux/keyctl.h> 3101 #include <sys/syscall.h> 3102 #include <unistd.h> 3103 int main(void) { 3104 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 3105 }'''), error_message: 'keyctl syscall not available on this system').allowed() 3106config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 3107 3108have_cpuid_h = cc.links(''' 3109 #include <cpuid.h> 3110 int main(void) { 3111 unsigned a, b, c, d; 3112 unsigned max = __get_cpuid_max(0, 0); 3113 3114 if (max >= 1) { 3115 __cpuid(1, a, b, c, d); 3116 } 3117 3118 if (max >= 7) { 3119 __cpuid_count(7, 0, a, b, c, d); 3120 } 3121 3122 return 0; 3123 }''') 3124config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 3125 3126# Don't bother to advertise asm/hwprobe.h for old versions that do 3127# not contain RISCV_HWPROBE_EXT_ZBA. 3128config_host_data.set('CONFIG_ASM_HWPROBE_H', 3129 cc.has_header_symbol('asm/hwprobe.h', 3130 'RISCV_HWPROBE_EXT_ZBA')) 3131 3132if have_cpuid_h 3133 have_avx2 = cc.links(''' 3134 #include <immintrin.h> 3135 static int __attribute__((target("avx2"))) bar(void *a) { 3136 __m256i x = *(__m256i *)a; 3137 return _mm256_testz_si256(x, x); 3138 } 3139 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 3140 ''') 3141 have_avx512bw = cc.links(''' 3142 #include <immintrin.h> 3143 static int __attribute__((target("avx512bw"))) bar(void *a) { 3144 __m512i *x = a; 3145 __m512i res= _mm512_abs_epi8(*x); 3146 return res[1]; 3147 } 3148 int main(int argc, char *argv[]) { return bar(argv[0]); } 3149 ''') 3150 if get_option('x86_version') >= '3' and not have_avx2 3151 error('Cannot enable AVX optimizations due to missing intrinsics') 3152 elif get_option('x86_version') >= '4' and not have_avx512bw 3153 error('Cannot enable AVX512 optimizations due to missing intrinsics') 3154 endif 3155else 3156 have_avx2 = false 3157 have_avx512bw = false 3158 if get_option('x86_version') >= '3' 3159 error('Cannot enable AVX optimizations due to missing cpuid.h') 3160 endif 3161endif 3162config_host_data.set('CONFIG_AVX2_OPT', have_avx2) 3163config_host_data.set('CONFIG_AVX512BW_OPT', have_avx512bw) 3164 3165# For both AArch64 and AArch32, detect if builtins are available. 3166config_host_data.set('CONFIG_ARM_AES_BUILTIN', cc.compiles(''' 3167 #include <arm_neon.h> 3168 #ifndef __ARM_FEATURE_AES 3169 __attribute__((target("+crypto"))) 3170 #endif 3171 void foo(uint8x16_t *p) { *p = vaesmcq_u8(*p); } 3172 ''')) 3173 3174if get_option('membarrier').disabled() 3175 have_membarrier = false 3176elif host_os == 'windows' 3177 have_membarrier = true 3178elif host_os == 'linux' 3179 have_membarrier = cc.compiles(''' 3180 #include <linux/membarrier.h> 3181 #include <sys/syscall.h> 3182 #include <unistd.h> 3183 #include <stdlib.h> 3184 int main(void) { 3185 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 3186 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 3187 exit(0); 3188 }''') 3189endif 3190config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 3191 .require(have_membarrier, error_message: 'membarrier system call not available') \ 3192 .allowed()) 3193 3194have_afalg = get_option('crypto_afalg') \ 3195 .require(cc.compiles(osdep_prefix + ''' 3196 #include <sys/socket.h> 3197 #include <linux/if_alg.h> 3198 int main(void) { 3199 int sock; 3200 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 3201 return sock; 3202 } 3203 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 3204config_host_data.set('CONFIG_AF_ALG', have_afalg) 3205 3206config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 3207 'linux/vm_sockets.h', 'AF_VSOCK', 3208 prefix: '#include <sys/socket.h>', 3209)) 3210 3211have_vss = false 3212have_vss_sdk = false # old xp/2003 SDK 3213if host_os == 'windows' and 'cpp' in all_languages 3214 have_vss = cxx.compiles(''' 3215 #define __MIDL_user_allocate_free_DEFINED__ 3216 #include <vss.h> 3217 int main(void) { return VSS_CTX_BACKUP; }''') 3218 have_vss_sdk = cxx.has_header('vscoordint.h') 3219endif 3220config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 3221 3222# Older versions of MinGW do not import _lock_file and _unlock_file properly. 3223# This was fixed for v6.0.0 with commit b48e3ac8969d. 3224if host_os == 'windows' 3225 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 3226 #include <stdio.h> 3227 int main(void) { 3228 _lock_file(NULL); 3229 _unlock_file(NULL); 3230 return 0; 3231 }''', name: '_lock_file and _unlock_file')) 3232endif 3233 3234if spice.found() 3235 config_host_data.set('HAVE_SPICE_QXL_GL_SCANOUT2', 3236 cc.has_function('spice_qxl_gl_scanout2', dependencies: spice)) 3237endif 3238 3239if host_os == 'windows' 3240 mingw_has_setjmp_longjmp = cc.links(''' 3241 #include <setjmp.h> 3242 int main(void) { 3243 /* 3244 * These functions are not available in setjmp header, but may be 3245 * available at link time, from libmingwex.a. 3246 */ 3247 extern int __mingw_setjmp(jmp_buf); 3248 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int); 3249 jmp_buf env; 3250 __mingw_setjmp(env); 3251 __mingw_longjmp(env, 0); 3252 } 3253 ''', name: 'mingw setjmp and longjmp') 3254 3255 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp 3256 error('mingw must provide setjmp/longjmp for windows-arm64') 3257 endif 3258endif 3259 3260# Detect host pointer size for the target configuration loop. 3261host_long_bits = cc.sizeof('void *') * 8 3262 3263######################## 3264# Target configuration # 3265######################## 3266 3267minikconf = find_program('scripts/minikconf.py') 3268 3269config_all_accel = {} 3270config_all_devices = {} 3271config_devices_mak_list = [] 3272config_devices_h = {} 3273config_target_h = {} 3274config_target_mak = {} 3275config_base_arch_mak = {} 3276 3277disassemblers = { 3278 'alpha' : ['CONFIG_ALPHA_DIS'], 3279 'avr' : ['CONFIG_AVR_DIS'], 3280 'hexagon' : ['CONFIG_HEXAGON_DIS'], 3281 'hppa' : ['CONFIG_HPPA_DIS'], 3282 'i386' : ['CONFIG_I386_DIS'], 3283 'x86_64' : ['CONFIG_I386_DIS'], 3284 'm68k' : ['CONFIG_M68K_DIS'], 3285 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 3286 'mips' : ['CONFIG_MIPS_DIS'], 3287 'or1k' : ['CONFIG_OPENRISC_DIS'], 3288 'ppc' : ['CONFIG_PPC_DIS'], 3289 'riscv' : ['CONFIG_RISCV_DIS'], 3290 'rx' : ['CONFIG_RX_DIS'], 3291 's390' : ['CONFIG_S390_DIS'], 3292 'sh4' : ['CONFIG_SH4_DIS'], 3293 'sparc' : ['CONFIG_SPARC_DIS'], 3294 'xtensa' : ['CONFIG_XTENSA_DIS'], 3295 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 3296} 3297 3298have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 3299host_kconfig = \ 3300 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 3301 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 3302 (pixman.found() ? ['CONFIG_PIXMAN=y'] : []) + \ 3303 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 3304 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 3305 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 3306 (libcbor.found() ? ['CONFIG_LIBCBOR=y'] : []) + \ 3307 (gnutls.found() ? ['CONFIG_GNUTLS=y'] : []) + \ 3308 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 3309 (fdt.found() ? ['CONFIG_FDT=y'] : []) + \ 3310 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 3311 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 3312 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 3313 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 3314 (host_os == 'linux' ? ['CONFIG_LINUX=y'] : []) + \ 3315 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 3316 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) + \ 3317 (hv_balloon ? ['CONFIG_HV_BALLOON_POSSIBLE=y'] : []) + \ 3318 (have_rust ? ['CONFIG_HAVE_RUST=y'] : []) 3319 3320ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 3321 3322default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 3323actual_target_dirs = [] 3324fdt_required = [] 3325foreach target : target_dirs 3326 config_target = { 'TARGET_NAME': target.split('-')[0] } 3327 if target.endswith('linux-user') 3328 if host_os != 'linux' 3329 if default_targets 3330 continue 3331 endif 3332 error('Target @0@ is only available on a Linux host'.format(target)) 3333 endif 3334 config_target += { 'CONFIG_LINUX_USER': 'y' } 3335 elif target.endswith('bsd-user') 3336 if host_os not in bsd_oses 3337 if default_targets 3338 continue 3339 endif 3340 error('Target @0@ is only available on a BSD host'.format(target)) 3341 endif 3342 config_target += { 'CONFIG_BSD_USER': 'y' } 3343 elif target.endswith('softmmu') 3344 config_target += { 'CONFIG_SYSTEM_ONLY': 'y' } 3345 config_target += { 'CONFIG_SOFTMMU': 'y' } 3346 endif 3347 if target.endswith('-user') 3348 config_target += { 3349 'CONFIG_USER_ONLY': 'y', 3350 'CONFIG_QEMU_INTERP_PREFIX': 3351 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']), 3352 'CONFIG_QEMU_RTSIG_MAP': get_option('rtsig_map'), 3353 } 3354 endif 3355 3356 config_target += keyval.load('configs/targets' / target + '.mak') 3357 3358 target_kconfig = [] 3359 foreach sym: accelerators 3360 # Disallow 64-bit on 32-bit emulation and virtualization 3361 if host_long_bits < config_target['TARGET_LONG_BITS'].to_int() 3362 continue 3363 endif 3364 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 3365 config_target += { sym: 'y' } 3366 config_all_accel += { sym: 'y' } 3367 target_kconfig += [ sym + '=y' ] 3368 endif 3369 endforeach 3370 if target_kconfig.length() == 0 3371 if default_targets 3372 continue 3373 endif 3374 error('No accelerator available for target @0@'.format(target)) 3375 endif 3376 3377 if 'TARGET_NEED_FDT' in config_target and not fdt.found() 3378 if default_targets 3379 warning('Disabling ' + target + ' due to missing libfdt') 3380 else 3381 fdt_required += target 3382 endif 3383 continue 3384 endif 3385 3386 actual_target_dirs += target 3387 3388 # Add default keys 3389 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 3390 if 'TARGET_BASE_ARCH' not in config_target 3391 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 3392 endif 3393 if 'TARGET_ABI_DIR' not in config_target 3394 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 3395 endif 3396 if 'TARGET_BIG_ENDIAN' not in config_target 3397 config_target += {'TARGET_BIG_ENDIAN': 'n'} 3398 endif 3399 3400 foreach k, v: disassemblers 3401 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 3402 foreach sym: v 3403 config_target += { sym: 'y' } 3404 endforeach 3405 endif 3406 endforeach 3407 3408 config_target_data = configuration_data() 3409 foreach k, v: config_target 3410 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 3411 # do nothing 3412 elif ignored.contains(k) 3413 # do nothing 3414 elif k == 'TARGET_BASE_ARCH' 3415 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 3416 # not used to select files from sourcesets. 3417 config_target_data.set('TARGET_' + v.to_upper(), 1) 3418 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 3419 config_target_data.set_quoted(k, v) 3420 elif v == 'y' 3421 config_target_data.set(k, 1) 3422 elif v == 'n' 3423 config_target_data.set(k, 0) 3424 else 3425 config_target_data.set(k, v) 3426 endif 3427 endforeach 3428 config_target_data.set('QEMU_ARCH', 3429 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 3430 config_target_h += {target: configure_file(output: target + '-config-target.h', 3431 configuration: config_target_data)} 3432 3433 if target.endswith('-softmmu') 3434 target_kconfig += 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y' 3435 target_kconfig += 'CONFIG_TARGET_BIG_ENDIAN=' + config_target['TARGET_BIG_ENDIAN'] 3436 3437 # PVG is not cross-architecture. Use accelerator_targets as a proxy to 3438 # figure out which target can support PVG on this host 3439 if pvg.found() and target in accelerator_targets.get('CONFIG_HVF', []) 3440 target_kconfig += 'CONFIG_MAC_PVG=y' 3441 endif 3442 3443 config_input = meson.get_external_property(target, 'default') 3444 config_devices_mak = target + '-config-devices.mak' 3445 config_devices_mak = configure_file( 3446 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 3447 output: config_devices_mak, 3448 depfile: config_devices_mak + '.d', 3449 capture: true, 3450 command: [minikconf, 3451 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 3452 config_devices_mak, '@DEPFILE@', '@INPUT@', 3453 host_kconfig, target_kconfig]) 3454 3455 config_devices_data = configuration_data() 3456 config_devices = keyval.load(config_devices_mak) 3457 foreach k, v: config_devices 3458 config_devices_data.set(k, 1) 3459 endforeach 3460 config_devices_mak_list += config_devices_mak 3461 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 3462 configuration: config_devices_data)} 3463 config_target += config_devices 3464 config_all_devices += config_devices 3465 endif 3466 config_target_mak += {target: config_target} 3467 3468 # build a merged config for all targets with the same TARGET_BASE_ARCH 3469 target_base_arch = config_target['TARGET_BASE_ARCH'] 3470 config_base_arch = config_base_arch_mak.get(target_base_arch, {}) + config_target 3471 config_base_arch_mak += {target_base_arch: config_base_arch} 3472endforeach 3473target_dirs = actual_target_dirs 3474 3475target_configs_h = [] 3476foreach target: target_dirs 3477 target_configs_h += config_target_h[target] 3478 target_configs_h += config_devices_h.get(target, []) 3479endforeach 3480genh += custom_target('config-poison.h', 3481 input: [target_configs_h], 3482 output: 'config-poison.h', 3483 capture: true, 3484 command: [find_program('scripts/make-config-poison.sh'), 3485 target_configs_h]) 3486 3487if fdt_required.length() > 0 3488 error('fdt disabled but required by targets ' + ', '.join(fdt_required)) 3489endif 3490 3491############### 3492# Subprojects # 3493############### 3494 3495libvfio_user_dep = not_found 3496if have_system and vfio_user_server_allowed 3497 libvfio_user_proj = subproject('libvfio-user', required: true) 3498 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3499endif 3500 3501vhost_user = not_found 3502if host_os == 'linux' and have_vhost_user 3503 libvhost_user = subproject('libvhost-user') 3504 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3505endif 3506 3507libvduse = not_found 3508if have_libvduse 3509 libvduse_proj = subproject('libvduse') 3510 libvduse = libvduse_proj.get_variable('libvduse_dep') 3511endif 3512 3513##################### 3514# Generated sources # 3515##################### 3516 3517config_host_h = configure_file(output: 'config-host.h', configuration: config_host_data) 3518genh += config_host_h 3519 3520hxtool = find_program('scripts/hxtool') 3521shaderinclude = find_program('scripts/shaderinclude.py') 3522qapi_gen = find_program('scripts/qapi-gen.py') 3523qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3524 meson.current_source_dir() / 'scripts/qapi/commands.py', 3525 meson.current_source_dir() / 'scripts/qapi/common.py', 3526 meson.current_source_dir() / 'scripts/qapi/error.py', 3527 meson.current_source_dir() / 'scripts/qapi/events.py', 3528 meson.current_source_dir() / 'scripts/qapi/expr.py', 3529 meson.current_source_dir() / 'scripts/qapi/gen.py', 3530 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3531 meson.current_source_dir() / 'scripts/qapi/main.py', 3532 meson.current_source_dir() / 'scripts/qapi/parser.py', 3533 meson.current_source_dir() / 'scripts/qapi/schema.py', 3534 meson.current_source_dir() / 'scripts/qapi/source.py', 3535 meson.current_source_dir() / 'scripts/qapi/types.py', 3536 meson.current_source_dir() / 'scripts/qapi/features.py', 3537 meson.current_source_dir() / 'scripts/qapi/visit.py', 3538 meson.current_source_dir() / 'scripts/qapi-gen.py' 3539] 3540 3541tracetool = [ 3542 python, files('scripts/tracetool.py'), 3543 '--backend=' + ','.join(get_option('trace_backends')) 3544] 3545tracetool_depends = files( 3546 'scripts/tracetool/backend/log.py', 3547 'scripts/tracetool/backend/__init__.py', 3548 'scripts/tracetool/backend/dtrace.py', 3549 'scripts/tracetool/backend/ftrace.py', 3550 'scripts/tracetool/backend/simple.py', 3551 'scripts/tracetool/backend/syslog.py', 3552 'scripts/tracetool/backend/ust.py', 3553 'scripts/tracetool/format/ust_events_c.py', 3554 'scripts/tracetool/format/ust_events_h.py', 3555 'scripts/tracetool/format/__init__.py', 3556 'scripts/tracetool/format/d.py', 3557 'scripts/tracetool/format/simpletrace_stap.py', 3558 'scripts/tracetool/format/c.py', 3559 'scripts/tracetool/format/h.py', 3560 'scripts/tracetool/format/log_stap.py', 3561 'scripts/tracetool/format/stap.py', 3562 'scripts/tracetool/__init__.py', 3563) 3564 3565qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3566 meson.current_source_dir(), 3567 get_option('pkgversion'), meson.project_version()] 3568qemu_version = custom_target('qemu-version.h', 3569 output: 'qemu-version.h', 3570 command: qemu_version_cmd, 3571 capture: true, 3572 build_by_default: true, 3573 build_always_stale: true) 3574genh += qemu_version 3575 3576hxdep = [] 3577hx_headers = [ 3578 ['qemu-options.hx', 'qemu-options.def'], 3579 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3580] 3581if have_system 3582 hx_headers += [ 3583 ['hmp-commands.hx', 'hmp-commands.h'], 3584 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3585 ] 3586endif 3587foreach d : hx_headers 3588 hxdep += custom_target(d[1], 3589 input: files(d[0]), 3590 output: d[1], 3591 capture: true, 3592 command: [hxtool, '-h', '@INPUT0@']) 3593endforeach 3594genh += hxdep 3595 3596############### 3597# Trace files # 3598############### 3599 3600# TODO: add each directory to the subdirs from its own meson.build, once 3601# we have those 3602trace_events_subdirs = [ 3603 'crypto', 3604 'qapi', 3605 'qom', 3606 'monitor', 3607 'util', 3608 'gdbstub', 3609] 3610if have_linux_user 3611 trace_events_subdirs += [ 'linux-user' ] 3612endif 3613if have_bsd_user 3614 trace_events_subdirs += [ 'bsd-user' ] 3615endif 3616if have_block 3617 trace_events_subdirs += [ 3618 'authz', 3619 'block', 3620 'chardev', 3621 'io', 3622 'nbd', 3623 'scsi', 3624 ] 3625endif 3626if have_system 3627 trace_events_subdirs += [ 3628 'accel/kvm', 3629 'audio', 3630 'backends', 3631 'backends/tpm', 3632 'ebpf', 3633 'hw/9pfs', 3634 'hw/acpi', 3635 'hw/adc', 3636 'hw/alpha', 3637 'hw/arm', 3638 'hw/audio', 3639 'hw/block', 3640 'hw/char', 3641 'hw/display', 3642 'hw/dma', 3643 'hw/fsi', 3644 'hw/hyperv', 3645 'hw/i2c', 3646 'hw/i386', 3647 'hw/i386/xen', 3648 'hw/i386/kvm', 3649 'hw/ide', 3650 'hw/input', 3651 'hw/intc', 3652 'hw/isa', 3653 'hw/mem', 3654 'hw/mips', 3655 'hw/misc', 3656 'hw/misc/macio', 3657 'hw/net', 3658 'hw/net/can', 3659 'hw/nubus', 3660 'hw/nvme', 3661 'hw/nvram', 3662 'hw/pci', 3663 'hw/pci-host', 3664 'hw/ppc', 3665 'hw/rtc', 3666 'hw/riscv', 3667 'hw/s390x', 3668 'hw/scsi', 3669 'hw/sd', 3670 'hw/sensor', 3671 'hw/sh4', 3672 'hw/sparc', 3673 'hw/sparc64', 3674 'hw/ssi', 3675 'hw/timer', 3676 'hw/tpm', 3677 'hw/uefi', 3678 'hw/ufs', 3679 'hw/usb', 3680 'hw/vfio', 3681 'hw/virtio', 3682 'hw/vmapple', 3683 'hw/watchdog', 3684 'hw/xen', 3685 'hw/gpio', 3686 'migration', 3687 'net', 3688 'system', 3689 'ui', 3690 'hw/remote', 3691 ] 3692endif 3693if have_system or have_user 3694 trace_events_subdirs += [ 3695 'accel/tcg', 3696 'hw/core', 3697 'target/arm', 3698 'target/arm/hvf', 3699 'target/hppa', 3700 'target/i386', 3701 'target/i386/kvm', 3702 'target/loongarch', 3703 'target/mips/tcg', 3704 'target/ppc', 3705 'target/riscv', 3706 'target/s390x', 3707 'target/s390x/kvm', 3708 'target/sparc', 3709 ] 3710endif 3711 3712################### 3713# Collect sources # 3714################### 3715 3716authz_ss = ss.source_set() 3717blockdev_ss = ss.source_set() 3718block_ss = ss.source_set() 3719chardev_ss = ss.source_set() 3720common_ss = ss.source_set() 3721crypto_ss = ss.source_set() 3722hwcore_ss = ss.source_set() 3723io_ss = ss.source_set() 3724qmp_ss = ss.source_set() 3725qom_ss = ss.source_set() 3726system_ss = ss.source_set() 3727specific_fuzz_ss = ss.source_set() 3728specific_ss = ss.source_set() 3729rust_devices_ss = ss.source_set() 3730stub_ss = ss.source_set() 3731trace_ss = ss.source_set() 3732user_ss = ss.source_set() 3733util_ss = ss.source_set() 3734 3735# accel modules 3736qtest_module_ss = ss.source_set() 3737 3738modules = {} 3739target_modules = {} 3740plugin_modules = [] 3741hw_arch = {} 3742target_arch = {} 3743target_system_arch = {} 3744target_user_arch = {} 3745hw_common_arch = {} 3746target_common_arch = {} 3747target_common_system_arch = {} 3748 3749# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3750# that is filled in by qapi/. 3751subdir('qapi') 3752subdir('qobject') 3753subdir('stubs') 3754subdir('trace') 3755subdir('util') 3756subdir('qom') 3757subdir('authz') 3758subdir('crypto') 3759subdir('ui') 3760subdir('gdbstub') 3761if have_system 3762 subdir('hw') 3763else 3764 subdir('hw/core') 3765endif 3766 3767if enable_modules 3768 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3769 modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO') 3770endif 3771 3772qom_ss = qom_ss.apply({}) 3773libqom = static_library('qom', qom_ss.sources() + genh, 3774 dependencies: [qom_ss.dependencies()], 3775 build_by_default: false) 3776qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false), 3777 dependencies: qom_ss.dependencies()) 3778 3779event_loop_base = files('event-loop-base.c') 3780event_loop_base = static_library('event-loop-base', 3781 sources: event_loop_base + genh, 3782 build_by_default: false) 3783event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false), 3784 dependencies: [qom]) 3785 3786stub_ss = stub_ss.apply({}) 3787 3788util_ss.add_all(trace_ss) 3789util_ss = util_ss.apply({}) 3790libqemuutil = static_library('qemuutil', 3791 build_by_default: false, 3792 sources: util_ss.sources() + stub_ss.sources() + genh, 3793 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc]) 3794qemuutil_deps = [event_loop_base] 3795if host_os != 'windows' 3796 qemuutil_deps += [rt] 3797endif 3798qemuutil = declare_dependency(link_with: libqemuutil, 3799 sources: genh + version_res, 3800 dependencies: qemuutil_deps) 3801 3802if have_system or have_user 3803 decodetree = generator(find_program('scripts/decodetree.py'), 3804 output: 'decode-@BASENAME@.c.inc', 3805 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3806 subdir('libdecnumber') 3807 subdir('target') 3808endif 3809 3810subdir('audio') 3811subdir('io') 3812subdir('chardev') 3813subdir('fsdev') 3814subdir('dump') 3815 3816if have_block 3817 block_ss.add(files( 3818 'block.c', 3819 'blockjob.c', 3820 'job.c', 3821 'qemu-io-cmds.c', 3822 )) 3823 if config_host_data.get('CONFIG_REPLICATION') 3824 block_ss.add(files('replication.c')) 3825 endif 3826 3827 subdir('nbd') 3828 subdir('scsi') 3829 subdir('block') 3830 3831 blockdev_ss.add(files( 3832 'blockdev.c', 3833 'blockdev-nbd.c', 3834 'iothread.c', 3835 'job-qmp.c', 3836 )) 3837 3838 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3839 # os-win32.c does not 3840 if host_os == 'windows' 3841 system_ss.add(files('os-win32.c')) 3842 elif host_os == 'emscripten' 3843 blockdev_ss.add(files('os-wasm.c')) 3844 else 3845 blockdev_ss.add(files('os-posix.c')) 3846 endif 3847endif 3848 3849common_ss.add(files('cpu-common.c')) 3850specific_ss.add(files('cpu-target.c')) 3851 3852subdir('system') 3853 3854# Work around a gcc bug/misfeature wherein constant propagation looks 3855# through an alias: 3856# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3857# to guess that a const variable is always zero. Without lto, this is 3858# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3859# without lto, not even the alias is required -- we simply use different 3860# declarations in different compilation units. 3861pagevary = files('page-vary-common.c') 3862if get_option('b_lto') 3863 pagevary_flags = ['-fno-lto'] 3864 if get_option('cfi') 3865 pagevary_flags += '-fno-sanitize=cfi-icall' 3866 endif 3867 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3868 c_args: pagevary_flags) 3869 pagevary = declare_dependency(link_with: pagevary) 3870endif 3871common_ss.add(pagevary) 3872specific_ss.add(files('page-target.c', 'page-vary-target.c')) 3873 3874common_ss.add(files('target-info.c')) 3875specific_ss.add(files('target-info-stub.c')) 3876 3877subdir('backends') 3878subdir('disas') 3879subdir('migration') 3880subdir('monitor') 3881subdir('net') 3882subdir('replay') 3883subdir('semihosting') 3884subdir('stats') 3885subdir('tcg') 3886subdir('fpu') 3887subdir('accel') 3888subdir('plugins') 3889subdir('ebpf') 3890 3891if 'CONFIG_TCG' in config_all_accel 3892 subdir('contrib/plugins') 3893endif 3894 3895common_user_inc = [] 3896 3897subdir('common-user') 3898subdir('bsd-user') 3899subdir('linux-user') 3900 3901# needed for fuzzing binaries 3902subdir('tests/qtest/libqos') 3903subdir('tests/qtest/fuzz') 3904 3905# accel modules 3906target_modules += { 'accel' : { 'qtest': qtest_module_ss }} 3907 3908############################################## 3909# Internal static_libraries and dependencies # 3910############################################## 3911 3912modinfo_collect = find_program('scripts/modinfo-collect.py') 3913modinfo_generate = find_program('scripts/modinfo-generate.py') 3914modinfo_files = [] 3915 3916block_mods = [] 3917system_mods = [] 3918emulator_modules = [] 3919foreach d, list : modules 3920 if not (d == 'block' ? have_block : have_system) 3921 continue 3922 endif 3923 3924 foreach m, module_ss : list 3925 if enable_modules 3926 module_ss.add(modulecommon) 3927 module_ss = module_ss.apply(config_all_devices, strict: false) 3928 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3929 dependencies: module_ss.dependencies(), pic: true) 3930 if d == 'block' 3931 block_mods += sl 3932 else 3933 system_mods += sl 3934 endif 3935 emulator_modules += shared_module(sl.name(), 3936 name_prefix: '', 3937 objects: sl.extract_all_objects(recursive: false), 3938 dependencies: module_ss.dependencies(), 3939 install: true, 3940 install_dir: qemu_moddir) 3941 if module_ss.sources() != [] 3942 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3943 output: d + '-' + m + '.modinfo', 3944 input: sl.extract_all_objects(recursive: true), 3945 capture: true, 3946 command: [modinfo_collect, '@INPUT@']) 3947 endif 3948 else 3949 if d == 'block' 3950 block_ss.add_all(module_ss) 3951 else 3952 system_ss.add_all(module_ss) 3953 endif 3954 endif 3955 endforeach 3956endforeach 3957 3958foreach d, list : target_modules 3959 foreach m, module_ss : list 3960 if enable_modules 3961 module_ss.add(modulecommon) 3962 foreach target : target_dirs 3963 if target.endswith('-softmmu') 3964 config_target = config_target_mak[target] 3965 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3966 c_args = ['-DCOMPILING_PER_TARGET', 3967 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3968 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3969 target_module_ss = module_ss.apply(config_target, strict: false) 3970 if target_module_ss.sources() != [] 3971 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3972 sl = static_library(module_name, 3973 [genh, target_module_ss.sources()], 3974 dependencies: target_module_ss.dependencies(), 3975 include_directories: target_inc, 3976 c_args: c_args, 3977 pic: true) 3978 system_mods += sl 3979 emulator_modules += shared_module(sl.name(), 3980 name_prefix: '', 3981 objects: sl.extract_all_objects(recursive: false), 3982 dependencies: target_module_ss.dependencies(), 3983 install: true, 3984 install_dir: qemu_moddir) 3985 modinfo_files += custom_target(module_name + '.modinfo', 3986 output: module_name + '.modinfo', 3987 input: sl.extract_all_objects(recursive: true), 3988 capture: true, 3989 command: [modinfo_collect, '--target', target, '@INPUT@']) 3990 endif 3991 endif 3992 endforeach 3993 else 3994 specific_ss.add_all(module_ss) 3995 endif 3996 endforeach 3997endforeach 3998 3999if enable_modules 4000 foreach target : target_dirs 4001 if target.endswith('-softmmu') 4002 config_target = config_target_mak[target] 4003 config_devices_mak = target + '-config-devices.mak' 4004 modinfo_src = custom_target('modinfo-' + target + '.c', 4005 output: 'modinfo-' + target + '.c', 4006 input: modinfo_files, 4007 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 4008 capture: true) 4009 4010 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 4011 modinfo_dep = declare_dependency(link_with: modinfo_lib) 4012 4013 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 4014 hw_arch[arch].add(modinfo_dep) 4015 endif 4016 endforeach 4017 4018 if emulator_modules.length() > 0 4019 alias_target('modules', emulator_modules) 4020 endif 4021endif 4022 4023nm = find_program('nm') 4024undefsym = find_program('scripts/undefsym.py') 4025block_syms = custom_target('block.syms', output: 'block.syms', 4026 input: [libqemuutil, block_mods], 4027 capture: true, 4028 command: [undefsym, nm, '@INPUT@']) 4029qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 4030 input: [libqemuutil, system_mods], 4031 capture: true, 4032 command: [undefsym, nm, '@INPUT@']) 4033 4034authz_ss = authz_ss.apply({}) 4035libauthz = static_library('authz', authz_ss.sources() + genh, 4036 dependencies: [authz_ss.dependencies()], 4037 build_by_default: false) 4038 4039authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false), 4040 dependencies: [authz_ss.dependencies(), qom]) 4041 4042crypto_ss = crypto_ss.apply({}) 4043libcrypto = static_library('crypto', crypto_ss.sources() + genh, 4044 dependencies: [crypto_ss.dependencies()], 4045 build_by_default: false) 4046 4047crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false), 4048 dependencies: [crypto_ss.dependencies(), authz, qom]) 4049 4050io_ss = io_ss.apply({}) 4051libio = static_library('io', io_ss.sources() + genh, 4052 dependencies: [io_ss.dependencies()], 4053 link_with: libqemuutil, 4054 build_by_default: false) 4055 4056io = declare_dependency(objects: libio.extract_all_objects(recursive: false), 4057 dependencies: [io_ss.dependencies(), crypto, qom]) 4058 4059libmigration = static_library('migration', sources: migration_files + genh, 4060 build_by_default: false) 4061migration = declare_dependency(objects: libmigration.extract_all_objects(recursive: false), 4062 dependencies: [qom, io]) 4063system_ss.add(migration) 4064 4065block_ss = block_ss.apply({}) 4066libblock = static_library('block', block_ss.sources() + genh, 4067 dependencies: block_ss.dependencies(), 4068 build_by_default: false) 4069 4070block = declare_dependency(objects: libblock.extract_all_objects(recursive: false), 4071 dependencies: [block_ss.dependencies(), crypto, io]) 4072 4073blockdev_ss = blockdev_ss.apply({}) 4074libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 4075 dependencies: blockdev_ss.dependencies(), 4076 build_by_default: false) 4077 4078blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false), 4079 dependencies: [blockdev_ss.dependencies(), block, event_loop_base]) 4080 4081qmp_ss = qmp_ss.apply({}) 4082libqmp = static_library('qmp', qmp_ss.sources() + genh, 4083 dependencies: qmp_ss.dependencies(), 4084 build_by_default: false) 4085 4086qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false), 4087 dependencies: qmp_ss.dependencies()) 4088 4089libchardev = static_library('chardev', chardev_ss.sources() + genh, 4090 dependencies: chardev_ss.dependencies(), 4091 build_by_default: false) 4092 4093chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), 4094 dependencies: [chardev_ss.dependencies(), io]) 4095 4096hwcore_ss = hwcore_ss.apply({}) 4097libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 4098 build_by_default: false) 4099hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false)) 4100common_ss.add(hwcore) 4101 4102########### 4103# Targets # 4104########### 4105 4106system_ss.add(authz, blockdev, chardev, crypto, io, qmp) 4107common_ss.add(qom, qemuutil) 4108 4109libuser = static_library('user', 4110 user_ss.all_sources() + genh, 4111 c_args: ['-DCONFIG_USER_ONLY', 4112 '-DCOMPILING_SYSTEM_VS_USER'], 4113 include_directories: common_user_inc, 4114 dependencies: user_ss.all_dependencies(), 4115 build_by_default: false) 4116 4117libsystem = static_library('system', 4118 system_ss.all_sources() + genh, 4119 c_args: ['-DCONFIG_SOFTMMU', 4120 '-DCOMPILING_SYSTEM_VS_USER'], 4121 dependencies: system_ss.all_dependencies(), 4122 build_by_default: false) 4123 4124# Note that this library is never used directly (only through extract_objects) 4125# and is not built by default; therefore, source files not used by the build 4126# configuration will be in build.ninja, but are never built by default. 4127common_all = static_library('common', 4128 build_by_default: false, 4129 sources: common_ss.all_sources() + genh, 4130 implicit_include_directories: false, 4131 dependencies: common_ss.all_dependencies()) 4132 4133# construct common libraries per base architecture 4134target_common_arch_libs = {} 4135target_common_system_arch_libs = {} 4136foreach target_base_arch, config_base_arch : config_base_arch_mak 4137 config_target = config_target_mak[target] 4138 target_inc = [include_directories('target' / target_base_arch)] 4139 inc = [common_user_inc + target_inc] 4140 4141 target_common = common_ss.apply(config_target, strict: false) 4142 target_system = system_ss.apply(config_target, strict: false) 4143 target_user = user_ss.apply(config_target, strict: false) 4144 common_deps = [] 4145 system_deps = [] 4146 user_deps = [] 4147 foreach dep: target_common.dependencies() 4148 common_deps += dep.partial_dependency(compile_args: true, includes: true) 4149 endforeach 4150 foreach dep: target_system.dependencies() 4151 system_deps += dep.partial_dependency(compile_args: true, includes: true) 4152 endforeach 4153 foreach dep: target_user.dependencies() 4154 user_deps += dep.partial_dependency(compile_args: true, includes: true) 4155 endforeach 4156 4157 # prevent common code to access cpu compile time definition, 4158 # but still allow access to cpu.h 4159 target_c_args = ['-DCPU_DEFS_H'] 4160 target_system_c_args = target_c_args + ['-DCOMPILING_SYSTEM_VS_USER', '-DCONFIG_SOFTMMU'] 4161 4162 if target_base_arch in target_common_arch 4163 src = target_common_arch[target_base_arch] 4164 lib = static_library( 4165 'common_' + target_base_arch, 4166 build_by_default: false, 4167 sources: src.all_sources() + genh, 4168 include_directories: inc, 4169 c_args: target_c_args, 4170 dependencies: src.all_dependencies() + common_deps + 4171 system_deps + user_deps) 4172 target_common_arch_libs += {target_base_arch: lib} 4173 endif 4174 4175 # merge hw_common_arch in target_common_system_arch 4176 if target_base_arch in hw_common_arch 4177 hw_src = hw_common_arch[target_base_arch] 4178 if target_base_arch in target_common_system_arch 4179 target_common_system_arch[target_base_arch].add_all(hw_src) 4180 else 4181 target_common_system_arch += {target_base_arch: hw_src} 4182 endif 4183 endif 4184 4185 if target_base_arch in target_common_system_arch 4186 src = target_common_system_arch[target_base_arch] 4187 lib = static_library( 4188 'system_' + target_base_arch, 4189 build_by_default: false, 4190 sources: src.all_sources() + genh, 4191 include_directories: inc, 4192 c_args: target_system_c_args, 4193 dependencies: src.all_dependencies() + common_deps + system_deps) 4194 target_common_system_arch_libs += {target_base_arch: lib} 4195 endif 4196endforeach 4197 4198if have_rust 4199 # We would like to use --generate-cstr, but it is only available 4200 # starting with bindgen 0.66.0. The oldest supported versions 4201 # is 0.60.x (Debian 12 has 0.60.1) which introduces --allowlist-file. 4202 bindgen_args = [ 4203 '--disable-header-comment', 4204 '--raw-line', '// @generated', 4205 '--ctypes-prefix', 'std::os::raw', 4206 '--generate-block', 4207 '--impl-debug', 4208 '--no-doc-comments', 4209 '--with-derive-default', 4210 '--no-layout-tests', 4211 '--no-prepend-enum-name', 4212 '--allowlist-file', meson.project_source_root() + '/include/.*', 4213 '--allowlist-file', meson.project_source_root() + '/.*', 4214 '--allowlist-file', meson.project_build_root() + '/.*' 4215 ] 4216 if not rustfmt.found() 4217 if bindgen.version().version_compare('<0.65.0') 4218 bindgen_args += ['--no-rustfmt-bindings'] 4219 else 4220 bindgen_args += ['--formatter', 'none'] 4221 endif 4222 endif 4223 if bindgen.version().version_compare('>=0.66.0') 4224 bindgen_args += ['--rust-target', '1.59'] 4225 endif 4226 if bindgen.version().version_compare('<0.61.0') 4227 # default in 0.61+ 4228 bindgen_args += ['--size_t-is-usize'] 4229 else 4230 bindgen_args += ['--merge-extern-blocks'] 4231 endif 4232 c_enums = [ 4233 'DeviceCategory', 4234 'GpioPolarity', 4235 'MachineInitPhase', 4236 'MemoryDeviceInfoKind', 4237 'MigrationPolicy', 4238 'MigrationPriority', 4239 'QEMUChrEvent', 4240 'QEMUClockType', 4241 'ResetType', 4242 'device_endian', 4243 'module_init_type', 4244 ] 4245 foreach enum : c_enums 4246 bindgen_args += ['--rustified-enum', enum] 4247 endforeach 4248 c_bitfields = [ 4249 'ClockEvent', 4250 'VMStateFlags', 4251 ] 4252 foreach enum : c_bitfields 4253 bindgen_args += ['--bitfield-enum', enum] 4254 endforeach 4255 4256 # TODO: Remove this comment when the clang/libclang mismatch issue is solved. 4257 # 4258 # Rust bindings generation with `bindgen` might fail in some cases where the 4259 # detected `libclang` does not match the expected `clang` version/target. In 4260 # this case you must pass the path to `clang` and `libclang` to your build 4261 # command invocation using the environment variables CLANG_PATH and 4262 # LIBCLANG_PATH 4263 bindings_rs = rust.bindgen( 4264 input: 'rust/wrapper.h', 4265 dependencies: common_ss.all_dependencies(), 4266 output: 'bindings.inc.rs', 4267 include_directories: include_directories('.', 'include'), 4268 bindgen_version: ['>=0.60.0'], 4269 args: bindgen_args, 4270 ) 4271 subdir('rust') 4272endif 4273 4274 4275feature_to_c = find_program('scripts/feature_to_c.py') 4276rust_root_crate = find_program('scripts/rust/rust_root_crate.sh') 4277 4278if host_os == 'darwin' 4279 entitlement = find_program('scripts/entitlement.sh') 4280endif 4281 4282traceable = [] 4283emulators = {} 4284foreach target : target_dirs 4285 config_target = config_target_mak[target] 4286 target_name = config_target['TARGET_NAME'] 4287 target_base_arch = config_target['TARGET_BASE_ARCH'] 4288 arch_srcs = [config_target_h[target]] 4289 arch_deps = [] 4290 c_args = ['-DCOMPILING_PER_TARGET', 4291 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 4292 ] 4293 link_args = emulator_link_args 4294 4295 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 4296 if host_os == 'linux' 4297 target_inc += include_directories('linux-headers', is_system: true) 4298 endif 4299 if target.endswith('-softmmu') 4300 target_type='system' 4301 t = target_system_arch[target_base_arch].apply(config_target, strict: false) 4302 arch_srcs += t.sources() 4303 arch_deps += t.dependencies() 4304 4305 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 4306 if hw_arch.has_key(hw_dir) 4307 hw = hw_arch[hw_dir].apply(config_target, strict: false) 4308 arch_srcs += hw.sources() 4309 arch_deps += hw.dependencies() 4310 endif 4311 4312 c_args += ['-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 4313 arch_srcs += config_devices_h[target] 4314 link_args += ['@block.syms', '@qemu.syms'] 4315 else 4316 abi = config_target['TARGET_ABI_DIR'] 4317 target_type='user' 4318 target_inc += common_user_inc 4319 if target_base_arch in target_user_arch 4320 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 4321 arch_srcs += t.sources() 4322 arch_deps += t.dependencies() 4323 endif 4324 if 'CONFIG_LINUX_USER' in config_target 4325 base_dir = 'linux-user' 4326 endif 4327 if 'CONFIG_BSD_USER' in config_target 4328 base_dir = 'bsd-user' 4329 target_inc += include_directories('bsd-user/' / host_os) 4330 target_inc += include_directories('bsd-user/host/' / host_arch) 4331 dir = base_dir / abi 4332 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 4333 endif 4334 target_inc += include_directories( 4335 base_dir, 4336 base_dir / abi, 4337 ) 4338 if 'CONFIG_LINUX_USER' in config_target 4339 dir = base_dir / abi 4340 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 4341 if config_target.has_key('TARGET_SYSTBL_ABI') 4342 arch_srcs += \ 4343 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 4344 extra_args : config_target['TARGET_SYSTBL_ABI']) 4345 endif 4346 endif 4347 endif 4348 4349 if 'TARGET_XML_FILES' in config_target 4350 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 4351 output: target + '-gdbstub-xml.c', 4352 input: files(config_target['TARGET_XML_FILES'].split()), 4353 command: [feature_to_c, '@INPUT@'], 4354 capture: true) 4355 arch_srcs += gdbstub_xml 4356 endif 4357 4358 t = target_arch[target_base_arch].apply(config_target, strict: false) 4359 arch_srcs += t.sources() 4360 arch_deps += t.dependencies() 4361 4362 target_common = common_ss.apply(config_target, strict: false) 4363 objects = [common_all.extract_objects(target_common.sources())] 4364 arch_deps += target_common.dependencies() 4365 if target_base_arch in target_common_arch_libs 4366 src = target_common_arch[target_base_arch].apply(config_target, strict: false) 4367 lib = target_common_arch_libs[target_base_arch] 4368 objects += lib.extract_objects(src.sources()) 4369 arch_deps += src.dependencies() 4370 endif 4371 if target_type == 'system' 4372 src = system_ss.apply(config_target, strict: false) 4373 objects += libsystem.extract_objects(src.sources()) 4374 arch_deps += src.dependencies() 4375 endif 4376 if target_type == 'user' 4377 src = user_ss.apply(config_target, strict: false) 4378 objects += libuser.extract_objects(src.sources()) 4379 arch_deps += src.dependencies() 4380 endif 4381 if target_type == 'system' and target_base_arch in target_common_system_arch_libs 4382 src = target_common_system_arch[target_base_arch].apply(config_target, strict: false) 4383 lib = target_common_system_arch_libs[target_base_arch] 4384 objects += lib.extract_objects(src.sources()) 4385 arch_deps += src.dependencies() 4386 endif 4387 4388 target_specific = specific_ss.apply(config_target, strict: false) 4389 arch_srcs += target_specific.sources() 4390 arch_deps += target_specific.dependencies() 4391 4392 if have_rust and target_type == 'system' 4393 target_rust = rust_devices_ss.apply(config_target, strict: false) 4394 crates = [] 4395 foreach dep : target_rust.dependencies() 4396 crates += dep.get_variable('crate') 4397 endforeach 4398 if crates.length() > 0 4399 rlib_rs = custom_target('rust_' + target.underscorify() + '.rs', 4400 output: 'rust_' + target.underscorify() + '.rs', 4401 command: [rust_root_crate, crates], 4402 capture: true, 4403 build_by_default: true, 4404 build_always_stale: true) 4405 rlib = static_library('rust_' + target.underscorify(), 4406 rlib_rs, 4407 dependencies: target_rust.dependencies(), 4408 override_options: ['rust_std=2021', 'build.rust_std=2021'], 4409 rust_abi: 'c') 4410 arch_deps += declare_dependency(link_whole: [rlib]) 4411 endif 4412 endif 4413 4414 # allow using headers from the dependencies but do not include the sources, 4415 # because this emulator only needs those in "objects". For external 4416 # dependencies, the full dependency is included below in the executable. 4417 lib_deps = [] 4418 foreach dep : arch_deps 4419 lib_deps += dep.partial_dependency(compile_args: true, includes: true) 4420 endforeach 4421 4422 lib = static_library('qemu-' + target, 4423 sources: arch_srcs + genh, 4424 dependencies: lib_deps, 4425 objects: objects, 4426 include_directories: target_inc, 4427 c_args: c_args, 4428 build_by_default: false) 4429 4430 if target.endswith('-softmmu') 4431 execs = [{ 4432 'name': 'qemu-system-' + target_name, 4433 'win_subsystem': 'console', 4434 'sources': files('system/main.c'), 4435 'dependencies': [sdl] 4436 }] 4437 if host_os == 'windows' and (sdl.found() or gtk.found()) 4438 execs += [{ 4439 'name': 'qemu-system-' + target_name + 'w', 4440 'win_subsystem': 'windows', 4441 'sources': files('system/main.c'), 4442 'dependencies': [sdl] 4443 }] 4444 endif 4445 if get_option('fuzzing') 4446 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 4447 execs += [{ 4448 'name': 'qemu-fuzz-' + target_name, 4449 'win_subsystem': 'console', 4450 'sources': specific_fuzz.sources(), 4451 'dependencies': specific_fuzz.dependencies(), 4452 }] 4453 endif 4454 else 4455 execs = [{ 4456 'name': 'qemu-' + target_name, 4457 'win_subsystem': 'console', 4458 'sources': [], 4459 'dependencies': [] 4460 }] 4461 endif 4462 foreach exe: execs 4463 exe_name = exe['name'] 4464 if host_os == 'darwin' 4465 exe_name += '-unsigned' 4466 endif 4467 4468 emulator = executable(exe_name, exe['sources'], 4469 install: true, 4470 c_args: c_args, 4471 dependencies: arch_deps + exe['dependencies'], 4472 objects: lib.extract_all_objects(recursive: true), 4473 link_depends: [block_syms, qemu_syms], 4474 link_args: link_args, 4475 win_subsystem: exe['win_subsystem']) 4476 4477 if host_os == 'darwin' 4478 icon = 'pc-bios/qemu.rsrc' 4479 build_input = [emulator, files(icon)] 4480 install_input = [ 4481 get_option('bindir') / exe_name, 4482 meson.current_source_dir() / icon 4483 ] 4484 if 'CONFIG_HVF' in config_target 4485 entitlements = 'accel/hvf/entitlements.plist' 4486 build_input += files(entitlements) 4487 install_input += meson.current_source_dir() / entitlements 4488 endif 4489 4490 emulators += {exe['name'] : custom_target(exe['name'], 4491 input: build_input, 4492 output: exe['name'], 4493 command: [entitlement, '@OUTPUT@', '@INPUT@']) 4494 } 4495 4496 meson.add_install_script(entitlement, '--install', 4497 get_option('bindir') / exe['name'], 4498 install_input) 4499 else 4500 emulators += {exe['name']: emulator} 4501 endif 4502 4503 traceable += [{ 4504 'exe': exe['name'], 4505 'probe-prefix': 'qemu.' + target_type + '.' + target_name, 4506 }] 4507 4508 endforeach 4509endforeach 4510 4511# Other build targets 4512 4513if get_option('plugins') 4514 install_headers('include/qemu/qemu-plugin.h') 4515 if host_os == 'windows' 4516 # On windows, we want to deliver the qemu_plugin_api.lib file in the qemu installer, 4517 # so that plugin authors can compile against it. 4518 install_data(win32_qemu_plugin_api_lib, install_dir: 'lib') 4519 endif 4520endif 4521 4522subdir('qga') 4523 4524# Don't build qemu-keymap if xkbcommon is not explicitly enabled 4525# when we don't build tools or system 4526if xkbcommon.found() 4527 # used for the update-keymaps target, so include rules even if !have_tools 4528 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 4529 dependencies: [qemuutil, xkbcommon], install: have_tools) 4530endif 4531 4532if have_tools 4533 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 4534 link_args: '@block.syms', link_depends: block_syms, 4535 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 4536 qemu_io = executable('qemu-io', files('qemu-io.c'), 4537 link_args: '@block.syms', link_depends: block_syms, 4538 dependencies: [block, qemuutil], install: true) 4539 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 4540 link_args: '@block.syms', link_depends: block_syms, 4541 dependencies: [blockdev, qemuutil, selinux], 4542 install: true) 4543 4544 subdir('storage-daemon') 4545 4546 foreach exe: [ 'qemu-img', 'qemu-io', 'qemu-nbd', 'qemu-storage-daemon'] 4547 traceable += [{ 4548 'exe': exe, 4549 'probe-prefix': 'qemu.' + exe.substring(5).replace('-', '_') 4550 }] 4551 endforeach 4552 4553 subdir('contrib/elf2dmp') 4554 4555 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 4556 dependencies: [qemuutil, rt], 4557 install: true) 4558 4559 if have_vhost_user 4560 subdir('contrib/vhost-user-blk') 4561 subdir('contrib/vhost-user-gpu') 4562 subdir('contrib/vhost-user-input') 4563 subdir('contrib/vhost-user-scsi') 4564 endif 4565 4566 if host_os == 'linux' 4567 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 4568 dependencies: [qemuutil, libcap_ng], 4569 install: true, 4570 install_dir: get_option('libexecdir')) 4571 4572 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 4573 dependencies: [authz, crypto, io, qom, qemuutil, 4574 libcap_ng, mpathpersist], 4575 install: true) 4576 4577 if cpu in ['x86', 'x86_64'] 4578 executable('qemu-vmsr-helper', files('tools/i386/qemu-vmsr-helper.c'), 4579 dependencies: [authz, crypto, io, qom, qemuutil, 4580 libcap_ng, mpathpersist], 4581 install: true) 4582 endif 4583 endif 4584 4585 if have_ivshmem 4586 subdir('contrib/ivshmem-client') 4587 subdir('contrib/ivshmem-server') 4588 endif 4589endif 4590 4591if stap.found() 4592 foreach t: traceable 4593 foreach stp: [ 4594 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / t['exe'], 'install': false}, 4595 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / t['exe'], 'install': true}, 4596 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 4597 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 4598 ] 4599 cmd = [ 4600 tracetool, '--group=all', '--format=' + stp['fmt'], 4601 '--binary=' + stp['bin'], 4602 '--probe-prefix=' + t['probe-prefix'], 4603 '@INPUT@', '@OUTPUT@' 4604 ] 4605 4606 custom_target(t['exe'] + stp['ext'], 4607 input: trace_events_all, 4608 output: t['exe'] + stp['ext'], 4609 install: stp['install'], 4610 install_dir: get_option('datadir') / 'systemtap/tapset', 4611 command: cmd, 4612 depend_files: tracetool_depends) 4613 endforeach 4614 endforeach 4615endif 4616 4617subdir('scripts') 4618subdir('tools') 4619subdir('pc-bios') 4620subdir('docs') 4621# Tests are disabled on emscripten because they rely on host features that aren't 4622# supported by emscripten (e.g. fork and unix socket). 4623if host_os != 'emscripten' 4624 subdir('tests') 4625endif 4626if gtk.found() 4627 subdir('po') 4628endif 4629 4630if host_machine.system() == 'windows' 4631 nsis_cmd = [ 4632 find_program('scripts/nsis.py'), 4633 '@OUTPUT@', 4634 get_option('prefix'), 4635 meson.current_source_dir(), 4636 glib_pc.get_variable('bindir'), 4637 host_machine.cpu(), 4638 '--', 4639 '-DDISPLAYVERSION=' + meson.project_version(), 4640 ] 4641 if build_docs 4642 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 4643 endif 4644 if gtk.found() 4645 nsis_cmd += '-DCONFIG_GTK=y' 4646 endif 4647 4648 nsis = custom_target('nsis', 4649 output: 'qemu-setup-' + meson.project_version() + '.exe', 4650 input: files('qemu.nsi'), 4651 build_always_stale: true, 4652 command: nsis_cmd + ['@INPUT@']) 4653 alias_target('installer', nsis) 4654endif 4655 4656######################### 4657# Configuration summary # 4658######################### 4659 4660# Build environment 4661summary_info = {} 4662summary_info += {'Build directory': meson.current_build_dir()} 4663summary_info += {'Source path': meson.current_source_dir()} 4664summary_info += {'Download dependencies': get_option('wrap_mode') != 'nodownload'} 4665summary(summary_info, bool_yn: true, section: 'Build environment') 4666 4667# Directories 4668summary_info += {'Install prefix': get_option('prefix')} 4669summary_info += {'BIOS directory': qemu_datadir} 4670pathsep = host_os == 'windows' ? ';' : ':' 4671summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4672summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4673summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4674summary_info += {'module directory': qemu_moddir} 4675summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4676summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4677summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4678if host_os != 'windows' 4679 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4680 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4681else 4682 summary_info += {'local state directory': 'queried at runtime'} 4683endif 4684summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4685summary(summary_info, bool_yn: true, section: 'Directories') 4686 4687# Host binaries 4688summary_info = {} 4689summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4690summary_info += {'sphinx-build': sphinx_build} 4691 4692# FIXME: the [binaries] section of machine files, which can be probed 4693# with find_program(), would be great for passing gdb and genisoimage 4694# paths from configure to Meson. However, there seems to be no way to 4695# hide a program (for example if gdb is too old). 4696if config_host.has_key('GDB') 4697 summary_info += {'gdb': config_host['GDB']} 4698endif 4699summary_info += {'iasl': iasl} 4700summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4701if host_os == 'windows' and have_ga 4702 summary_info += {'wixl': wixl} 4703endif 4704if slirp.found() and have_system 4705 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4706endif 4707summary(summary_info, bool_yn: true, section: 'Host binaries') 4708 4709# Configurable features 4710summary_info = {} 4711summary_info += {'Documentation': build_docs} 4712summary_info += {'system-mode emulation': have_system} 4713summary_info += {'user-mode emulation': have_user} 4714summary_info += {'block layer': have_block} 4715summary_info += {'Install blobs': get_option('install_blobs')} 4716summary_info += {'module support': enable_modules} 4717if enable_modules 4718 summary_info += {'alternative module path': get_option('module_upgrades')} 4719endif 4720summary_info += {'fuzzing support': get_option('fuzzing')} 4721if have_system 4722 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4723endif 4724summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4725if 'simple' in get_option('trace_backends') 4726 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4727endif 4728summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4729summary_info += {'Relocatable install': get_option('relocatable')} 4730summary_info += {'vhost-kernel support': have_vhost_kernel} 4731summary_info += {'vhost-net support': have_vhost_net} 4732summary_info += {'vhost-user support': have_vhost_user} 4733summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4734summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4735summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4736summary_info += {'build guest agent': have_ga} 4737summary(summary_info, bool_yn: true, section: 'Configurable features') 4738 4739# Compilation information 4740summary_info = {} 4741summary_info += {'host CPU': cpu} 4742summary_info += {'host endianness': build_machine.endian()} 4743summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4744summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4745if 'cpp' in all_languages 4746 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4747else 4748 summary_info += {'C++ compiler': false} 4749endif 4750if 'objc' in all_languages 4751 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4752else 4753 summary_info += {'Objective-C compiler': false} 4754endif 4755summary_info += {'Rust support': have_rust} 4756if have_rust 4757 summary_info += {'Rust target': config_host['RUST_TARGET_TRIPLE']} 4758 summary_info += {'rustc': ' '.join(rustc.cmd_array())} 4759 summary_info += {'rustc version': rustc.version()} 4760 summary_info += {'bindgen': bindgen.full_path()} 4761 summary_info += {'bindgen version': bindgen.version()} 4762endif 4763option_cflags = (get_option('debug') ? ['-g'] : []) 4764if get_option('optimization') != 'plain' 4765 option_cflags += ['-O' + get_option('optimization')] 4766endif 4767summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4768if 'cpp' in all_languages 4769 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4770endif 4771if 'objc' in all_languages 4772 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4773endif 4774link_args = get_option('c_link_args') 4775if link_args.length() > 0 4776 summary_info += {'LDFLAGS': ' '.join(link_args)} 4777endif 4778summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4779if 'cpp' in all_languages 4780 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4781endif 4782if 'objc' in all_languages 4783 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4784endif 4785summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4786summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4787summary_info += {'PIE': get_option('b_pie')} 4788summary_info += {'static build': get_option('prefer_static')} 4789summary_info += {'malloc trim support': has_malloc_trim} 4790summary_info += {'membarrier': have_membarrier} 4791summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4792summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4793summary_info += {'mutex debugging': get_option('debug_mutex')} 4794summary_info += {'memory allocator': get_option('malloc')} 4795summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4796summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4797summary_info += {'gcov': get_option('b_coverage')} 4798summary_info += {'thread sanitizer': get_option('tsan')} 4799summary_info += {'CFI support': get_option('cfi')} 4800if get_option('cfi') 4801 summary_info += {'CFI debug support': get_option('cfi_debug')} 4802endif 4803summary_info += {'strip binaries': get_option('strip')} 4804summary_info += {'sparse': sparse} 4805summary_info += {'mingw32 support': host_os == 'windows'} 4806summary(summary_info, bool_yn: true, section: 'Compilation') 4807 4808# snarf the cross-compilation information for tests 4809summary_info = {} 4810have_cross = false 4811foreach target: target_dirs 4812 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4813 if fs.exists(tcg_mak) 4814 config_cross_tcg = keyval.load(tcg_mak) 4815 if 'CC' in config_cross_tcg 4816 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4817 have_cross = true 4818 endif 4819 endif 4820endforeach 4821if have_cross 4822 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4823endif 4824 4825# Targets and accelerators 4826summary_info = {} 4827if have_system 4828 summary_info += {'KVM support': config_all_accel.has_key('CONFIG_KVM')} 4829 summary_info += {'HVF support': config_all_accel.has_key('CONFIG_HVF')} 4830 summary_info += {'WHPX support': config_all_accel.has_key('CONFIG_WHPX')} 4831 summary_info += {'NVMM support': config_all_accel.has_key('CONFIG_NVMM')} 4832 summary_info += {'Xen support': xen.found()} 4833 if xen.found() 4834 summary_info += {'xen ctrl version': xen.version()} 4835 endif 4836 summary_info += {'Xen emulation': config_all_devices.has_key('CONFIG_XEN_EMU')} 4837endif 4838summary_info += {'TCG support': config_all_accel.has_key('CONFIG_TCG')} 4839if config_all_accel.has_key('CONFIG_TCG') 4840 if get_option('tcg_interpreter') 4841 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4842 else 4843 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4844 endif 4845 summary_info += {'TCG plugins': get_option('plugins')} 4846 summary_info += {'TCG debug enabled': get_option('debug_tcg')} 4847 if have_linux_user or have_bsd_user 4848 summary_info += {'syscall buffer debugging support': get_option('debug_remap')} 4849 endif 4850endif 4851summary_info += {'target list': ' '.join(target_dirs)} 4852if have_system 4853 summary_info += {'default devices': get_option('default_devices')} 4854 summary_info += {'out of process emulation': multiprocess_allowed} 4855 summary_info += {'vfio-user server': vfio_user_server_allowed} 4856endif 4857summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4858 4859# Block layer 4860summary_info = {} 4861summary_info += {'coroutine backend': coroutine_backend} 4862summary_info += {'coroutine pool': have_coroutine_pool} 4863if have_block 4864 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4865 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4866 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4867 summary_info += {'VirtFS (9P) support': have_virtfs} 4868 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4869 summary_info += {'bochs support': get_option('bochs').allowed()} 4870 summary_info += {'cloop support': get_option('cloop').allowed()} 4871 summary_info += {'dmg support': get_option('dmg').allowed()} 4872 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4873 summary_info += {'vdi support': get_option('vdi').allowed()} 4874 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4875 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4876 summary_info += {'vpc support': get_option('vpc').allowed()} 4877 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4878 summary_info += {'qed support': get_option('qed').allowed()} 4879 summary_info += {'parallels support': get_option('parallels').allowed()} 4880 summary_info += {'FUSE exports': fuse} 4881 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4882endif 4883summary(summary_info, bool_yn: true, section: 'Block layer support') 4884 4885# Crypto 4886summary_info = {} 4887summary_info += {'TLS priority': get_option('tls_priority')} 4888summary_info += {'GNUTLS support': gnutls} 4889if gnutls.found() 4890 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4891endif 4892summary_info += {'libgcrypt': gcrypt} 4893summary_info += {'nettle': nettle} 4894if nettle.found() 4895 summary_info += {' XTS': xts != 'private'} 4896endif 4897summary_info += {'SM4 ALG support': crypto_sm4} 4898summary_info += {'SM3 ALG support': crypto_sm3} 4899summary_info += {'AF_ALG support': have_afalg} 4900summary_info += {'rng-none': get_option('rng_none')} 4901summary_info += {'Linux keyring': have_keyring} 4902summary_info += {'Linux keyutils': keyutils} 4903summary(summary_info, bool_yn: true, section: 'Crypto') 4904 4905# UI 4906summary_info = {} 4907if host_os == 'darwin' 4908 summary_info += {'Cocoa support': cocoa} 4909endif 4910summary_info += {'D-Bus display': dbus_display} 4911summary_info += {'SDL support': sdl} 4912summary_info += {'SDL image support': sdl_image} 4913summary_info += {'GTK support': gtk} 4914summary_info += {'pixman': pixman} 4915summary_info += {'VTE support': vte} 4916summary_info += {'PNG support': png} 4917summary_info += {'VNC support': vnc} 4918if vnc.found() 4919 summary_info += {'VNC SASL support': sasl} 4920 summary_info += {'VNC JPEG support': jpeg} 4921endif 4922summary_info += {'spice protocol support': spice_protocol} 4923if spice_protocol.found() 4924 summary_info += {' spice server support': spice} 4925endif 4926summary_info += {'curses support': curses} 4927summary_info += {'brlapi support': brlapi} 4928summary(summary_info, bool_yn: true, section: 'User interface') 4929 4930# Graphics backends 4931summary_info = {} 4932summary_info += {'VirGL support': virgl} 4933summary_info += {'Rutabaga support': rutabaga} 4934summary(summary_info, bool_yn: true, section: 'Graphics backends') 4935 4936# Audio backends 4937summary_info = {} 4938if host_os not in ['darwin', 'haiku', 'windows'] 4939 summary_info += {'OSS support': oss} 4940 summary_info += {'sndio support': sndio} 4941elif host_os == 'darwin' 4942 summary_info += {'CoreAudio support': coreaudio} 4943elif host_os == 'windows' 4944 summary_info += {'DirectSound support': dsound} 4945endif 4946if host_os == 'linux' 4947 summary_info += {'ALSA support': alsa} 4948 summary_info += {'PulseAudio support': pulse} 4949endif 4950summary_info += {'PipeWire support': pipewire} 4951summary_info += {'JACK support': jack} 4952summary(summary_info, bool_yn: true, section: 'Audio backends') 4953 4954# Network backends 4955summary_info = {} 4956if host_os == 'darwin' 4957 summary_info += {'vmnet.framework support': vmnet} 4958endif 4959summary_info += {'AF_XDP support': libxdp} 4960summary_info += {'slirp support': slirp} 4961summary_info += {'vde support': vde} 4962summary_info += {'netmap support': have_netmap} 4963summary_info += {'l2tpv3 support': have_l2tpv3} 4964summary(summary_info, bool_yn: true, section: 'Network backends') 4965 4966# Libraries 4967summary_info = {} 4968summary_info += {'libtasn1': tasn1} 4969summary_info += {'PAM': pam} 4970summary_info += {'iconv support': iconv} 4971summary_info += {'blkio support': blkio} 4972summary_info += {'curl support': curl} 4973summary_info += {'Multipath support': mpathpersist} 4974summary_info += {'Linux AIO support': libaio} 4975summary_info += {'Linux io_uring support': linux_io_uring} 4976summary_info += {'ATTR/XATTR support': libattr} 4977summary_info += {'RDMA support': rdma} 4978summary_info += {'fdt support': fdt_opt == 'internal' ? 'internal' : fdt} 4979summary_info += {'libcap-ng support': libcap_ng} 4980summary_info += {'bpf support': libbpf} 4981summary_info += {'rbd support': rbd} 4982summary_info += {'smartcard support': cacard} 4983summary_info += {'U2F support': u2f} 4984summary_info += {'libusb': libusb} 4985summary_info += {'usb net redir': usbredir} 4986summary_info += {'OpenGL support (epoxy)': opengl} 4987summary_info += {'GBM': gbm} 4988summary_info += {'libiscsi support': libiscsi} 4989summary_info += {'libnfs support': libnfs} 4990if host_os == 'windows' 4991 if have_ga 4992 summary_info += {'QGA VSS support': have_qga_vss} 4993 endif 4994endif 4995summary_info += {'seccomp support': seccomp} 4996summary_info += {'GlusterFS support': glusterfs} 4997summary_info += {'hv-balloon support': hv_balloon} 4998summary_info += {'TPM support': have_tpm} 4999summary_info += {'libssh support': libssh} 5000summary_info += {'lzo support': lzo} 5001summary_info += {'snappy support': snappy} 5002summary_info += {'bzip2 support': libbzip2} 5003summary_info += {'lzfse support': liblzfse} 5004summary_info += {'zstd support': zstd} 5005summary_info += {'Query Processing Library support': qpl} 5006summary_info += {'UADK Library support': uadk} 5007summary_info += {'qatzip support': qatzip} 5008summary_info += {'NUMA host support': numa} 5009summary_info += {'capstone': capstone} 5010summary_info += {'libpmem support': libpmem} 5011summary_info += {'libdaxctl support': libdaxctl} 5012summary_info += {'libcbor support': libcbor} 5013summary_info += {'libudev': libudev} 5014# Dummy dependency, keep .found() 5015summary_info += {'FUSE lseek': fuse_lseek.found()} 5016summary_info += {'selinux': selinux} 5017summary_info += {'libdw': libdw} 5018if host_os == 'freebsd' 5019 summary_info += {'libinotify-kqueue': inotify} 5020endif 5021if host_os == 'darwin' 5022 summary_info += {'ParavirtualizedGraphics support': pvg} 5023endif 5024summary_info += {'valgrind': valgrind} 5025summary(summary_info, bool_yn: true, section: 'Dependencies') 5026 5027if host_arch == 'unknown' 5028 message() 5029 warning('UNSUPPORTED HOST CPU') 5030 message() 5031 message('Support for CPU host architecture ' + cpu + ' is not currently') 5032 message('maintained. The QEMU project does not guarantee that QEMU will') 5033 message('compile or work on this host CPU. You can help by volunteering') 5034 message('to maintain it and providing a build host for our continuous') 5035 message('integration setup.') 5036 if have_tcg 5037 message() 5038 message('configure has succeeded and you can continue to build, but') 5039 message('QEMU will use a slow interpreter to emulate the target CPU.') 5040 endif 5041elif host_long_bits < 64 5042 message() 5043 warning('DEPRECATED HOST CPU') 5044 message() 5045 message('Support for 32-bit CPU host architecture ' + cpu + ' is going') 5046 message('to be dropped in a future QEMU release.') 5047endif 5048 5049if not supported_oses.contains(host_os) 5050 message() 5051 warning('UNSUPPORTED HOST OS') 5052 message() 5053 message('Support for host OS ' + host_os + 'is not currently maintained.') 5054 message('configure has succeeded and you can continue to build, but') 5055 message('the QEMU project does not guarantee that QEMU will compile or') 5056 message('work on this operating system. You can help by volunteering') 5057 message('to maintain it and providing a build host for our continuous') 5058 message('integration setup. This will ensure that future versions of QEMU') 5059 message('will keep working on ' + host_os + '.') 5060endif 5061 5062if host_arch == 'unknown' or not supported_oses.contains(host_os) 5063 message() 5064 message('If you want to help supporting QEMU on this platform, please') 5065 message('contact the developers at qemu-devel@nongnu.org.') 5066endif 5067 5068actually_reloc = get_option('relocatable') 5069# check if get_relocated_path() is actually able to relocate paths 5070if get_option('relocatable') and \ 5071 not (get_option('prefix') / get_option('bindir')).startswith(get_option('prefix') / '') 5072 message() 5073 warning('bindir not included within prefix, the installation will not be relocatable.') 5074 actually_reloc = false 5075endif 5076if not actually_reloc and (host_os == 'windows' or get_option('relocatable')) 5077 if host_os == 'windows' 5078 message() 5079 warning('Windows installs should usually be relocatable.') 5080 endif 5081 message() 5082 message('QEMU will have to be installed under ' + get_option('prefix') + '.') 5083 message('Use --disable-relocatable to remove this warning.') 5084endif 5085