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