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