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