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