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