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