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_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_parser')) 2109config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 2110config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 2111config_host_data.set('CONFIG_EBPF', libbpf.found()) 2112config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 2113config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 2114config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 2115config_host_data.set('CONFIG_LIBSSH', libssh.found()) 2116config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 2117config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 2118config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 2119config_host_data.set('CONFIG_MODULES', enable_modules) 2120config_host_data.set('CONFIG_NUMA', numa.found()) 2121if numa.found() 2122 config_host_data.set('HAVE_NUMA_HAS_PREFERRED_MANY', 2123 cc.has_function('numa_has_preferred_many', 2124 dependencies: numa)) 2125endif 2126config_host_data.set('CONFIG_OPENGL', opengl.found()) 2127config_host_data.set('CONFIG_PROFILER', get_option('profiler')) 2128config_host_data.set('CONFIG_RBD', rbd.found()) 2129config_host_data.set('CONFIG_RDMA', rdma.found()) 2130config_host_data.set('CONFIG_SAFESTACK', get_option('safe_stack')) 2131config_host_data.set('CONFIG_SDL', sdl.found()) 2132config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 2133config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 2134if seccomp.found() 2135 config_host_data.set('CONFIG_SECCOMP_SYSRAWRC', seccomp_has_sysrawrc) 2136endif 2137config_host_data.set('CONFIG_SNAPPY', snappy.found()) 2138config_host_data.set('CONFIG_TPM', have_tpm) 2139config_host_data.set('CONFIG_TSAN', get_option('tsan')) 2140config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 2141config_host_data.set('CONFIG_VDE', vde.found()) 2142config_host_data.set('CONFIG_VHOST_NET', have_vhost_net) 2143config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user) 2144config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa) 2145config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel) 2146config_host_data.set('CONFIG_VHOST_USER', have_vhost_user) 2147config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto) 2148config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa) 2149config_host_data.set('CONFIG_VMNET', vmnet.found()) 2150config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 2151config_host_data.set('CONFIG_VDUSE_BLK_EXPORT', have_vduse_blk_export) 2152config_host_data.set('CONFIG_PNG', png.found()) 2153config_host_data.set('CONFIG_VNC', vnc.found()) 2154config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 2155config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 2156config_host_data.set('CONFIG_VIRTFS', have_virtfs) 2157config_host_data.set('CONFIG_VTE', vte.found()) 2158config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 2159config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 2160config_host_data.set('CONFIG_GETTID', has_gettid) 2161config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 2162config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 2163config_host_data.set('CONFIG_TASN1', tasn1.found()) 2164config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 2165config_host_data.set('CONFIG_NETTLE', nettle.found()) 2166config_host_data.set('CONFIG_HOGWEED', hogweed.found()) 2167config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 2168config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 2169config_host_data.set('CONFIG_STATX', has_statx) 2170config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 2171config_host_data.set('CONFIG_ZSTD', zstd.found()) 2172config_host_data.set('CONFIG_FUSE', fuse.found()) 2173config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 2174config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 2175if spice_protocol.found() 2176config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 2177config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 2178config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 2179endif 2180config_host_data.set('CONFIG_SPICE', spice.found()) 2181config_host_data.set('CONFIG_X11', x11.found()) 2182config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 2183config_host_data.set('CONFIG_CFI', get_option('cfi')) 2184config_host_data.set('CONFIG_SELINUX', selinux.found()) 2185config_host_data.set('CONFIG_XEN_BACKEND', xen.found()) 2186config_host_data.set('CONFIG_LIBDW', libdw.found()) 2187if xen.found() 2188 # protect from xen.version() having less than three components 2189 xen_version = xen.version().split('.') + ['0', '0'] 2190 xen_ctrl_version = xen_version[0] + \ 2191 ('0' + xen_version[1]).substring(-2) + \ 2192 ('0' + xen_version[2]).substring(-2) 2193 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version) 2194endif 2195config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 2196config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 2197config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 2198config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 2199 2200config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 2201config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 2202 2203have_coroutine_pool = get_option('coroutine_pool') 2204if get_option('debug_stack_usage') and have_coroutine_pool 2205 message('Disabling coroutine pool to measure stack usage') 2206 have_coroutine_pool = false 2207endif 2208config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool) 2209config_host_data.set('CONFIG_DEBUG_GRAPH_LOCK', get_option('debug_graph_lock')) 2210config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 2211config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 2212config_host_data.set('CONFIG_GPROF', get_option('gprof')) 2213config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed()) 2214config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 2215config_host_data.set('CONFIG_REPLICATION', get_option('replication').allowed()) 2216 2217# has_header 2218config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 2219config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 2220config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 2221config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 2222config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 2223config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 2224config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 2225config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 2226config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 2227if targetos == 'windows' 2228 config_host_data.set('HAVE_AFUNIX_H', cc.has_header('afunix.h')) 2229endif 2230 2231# has_function 2232config_host_data.set('CONFIG_CLOSE_RANGE', cc.has_function('close_range')) 2233config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 2234config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 2235config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 2236config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 2237config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 2238# Note that we need to specify prefix: here to avoid incorrectly 2239# thinking that Windows has posix_memalign() 2240config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 2241config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 2242config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 2243config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 2244config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 2245config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 2246config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 2247config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 2248config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 2249config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 2250config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 2251config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 2252config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 2253config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) 2254config_host_data.set('HAVE_GLIB_WITH_SLICE_ALLOCATOR', glib_has_gslice) 2255config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 2256config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 2257config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 2258if rbd.found() 2259 config_host_data.set('HAVE_RBD_NAMESPACE_EXISTS', 2260 cc.has_function('rbd_namespace_exists', 2261 dependencies: rbd, 2262 prefix: '#include <rbd/librbd.h>')) 2263endif 2264if rdma.found() 2265 config_host_data.set('HAVE_IBV_ADVISE_MR', 2266 cc.has_function('ibv_advise_mr', 2267 dependencies: rdma, 2268 prefix: '#include <infiniband/verbs.h>')) 2269endif 2270 2271have_asan_fiber = false 2272if get_option('sanitizers') and \ 2273 not cc.has_function('__sanitizer_start_switch_fiber', 2274 args: '-fsanitize=address', 2275 prefix: '#include <sanitizer/asan_interface.h>') 2276 warning('Missing ASAN due to missing fiber annotation interface') 2277 warning('Without code annotation, the report may be inferior.') 2278else 2279 have_asan_fiber = true 2280endif 2281config_host_data.set('CONFIG_ASAN_IFACE_FIBER', have_asan_fiber) 2282 2283# has_header_symbol 2284config_host_data.set('CONFIG_BLKZONED', 2285 cc.has_header_symbol('linux/blkzoned.h', 'BLKOPENZONE')) 2286config_host_data.set('CONFIG_EPOLL_CREATE1', 2287 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 2288config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 2289 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 2290 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 2291config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 2292 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 2293config_host_data.set('CONFIG_FIEMAP', 2294 cc.has_header('linux/fiemap.h') and 2295 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 2296config_host_data.set('CONFIG_GETRANDOM', 2297 cc.has_function('getrandom') and 2298 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 2299config_host_data.set('CONFIG_INOTIFY', 2300 cc.has_header_symbol('sys/inotify.h', 'inotify_init')) 2301config_host_data.set('CONFIG_INOTIFY1', 2302 cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) 2303config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 2304 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 2305config_host_data.set('CONFIG_RTNETLINK', 2306 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 2307config_host_data.set('CONFIG_SYSMACROS', 2308 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 2309config_host_data.set('HAVE_OPTRESET', 2310 cc.has_header_symbol('getopt.h', 'optreset')) 2311config_host_data.set('HAVE_IPPROTO_MPTCP', 2312 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 2313 2314# has_member 2315config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 2316 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 2317 prefix: '#include <signal.h>')) 2318config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 2319 cc.has_member('struct stat', 'st_atim', 2320 prefix: '#include <sys/stat.h>')) 2321config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY', 2322 cc.has_member('struct blk_zone', 'capacity', 2323 prefix: '#include <linux/blkzoned.h>')) 2324 2325# has_type 2326config_host_data.set('CONFIG_IOVEC', 2327 cc.has_type('struct iovec', 2328 prefix: '#include <sys/uio.h>')) 2329config_host_data.set('HAVE_UTMPX', 2330 cc.has_type('struct utmpx', 2331 prefix: '#include <utmpx.h>')) 2332 2333config_host_data.set('CONFIG_EVENTFD', cc.links(''' 2334 #include <sys/eventfd.h> 2335 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 2336config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 2337 #include <unistd.h> 2338 int main(void) { 2339 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 2340 return fdatasync(0); 2341 #else 2342 #error Not supported 2343 #endif 2344 }''')) 2345 2346has_madvise = cc.links(gnu_source_prefix + ''' 2347 #include <sys/types.h> 2348 #include <sys/mman.h> 2349 #include <stddef.h> 2350 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 2351missing_madvise_proto = false 2352if has_madvise 2353 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 2354 # but forget to prototype it. In this case, has_madvise will be true (the 2355 # test program links despite a compile warning). To detect the 2356 # missing-prototype case, we try again with a definitely-bogus prototype. 2357 # This will only compile if the system headers don't provide the prototype; 2358 # otherwise the conflicting prototypes will cause a compiler error. 2359 missing_madvise_proto = cc.links(gnu_source_prefix + ''' 2360 #include <sys/types.h> 2361 #include <sys/mman.h> 2362 #include <stddef.h> 2363 extern int madvise(int); 2364 int main(void) { return madvise(0); }''') 2365endif 2366config_host_data.set('CONFIG_MADVISE', has_madvise) 2367config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 2368 2369config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 2370 #include <sys/mman.h> 2371 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 2372config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 2373 #include <fcntl.h> 2374 #if !defined(AT_EMPTY_PATH) 2375 # error missing definition 2376 #else 2377 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 2378 #endif''')) 2379config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 2380 #include <sys/mman.h> 2381 #include <stddef.h> 2382 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 2383 2384config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 2385 #include <pthread.h> 2386 2387 static void *f(void *p) { return NULL; } 2388 int main(void) 2389 { 2390 pthread_t thread; 2391 pthread_create(&thread, 0, f, 0); 2392 pthread_setname_np(thread, "QEMU"); 2393 return 0; 2394 }''', dependencies: threads)) 2395config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 2396 #include <pthread.h> 2397 2398 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 2399 int main(void) 2400 { 2401 pthread_t thread; 2402 pthread_create(&thread, 0, f, 0); 2403 return 0; 2404 }''', dependencies: threads)) 2405config_host_data.set('CONFIG_PTHREAD_SET_NAME_NP', cc.links(gnu_source_prefix + ''' 2406 #include <pthread.h> 2407 #include <pthread_np.h> 2408 2409 static void *f(void *p) { return NULL; } 2410 int main(void) 2411 { 2412 pthread_t thread; 2413 pthread_create(&thread, 0, f, 0); 2414 pthread_set_name_np(thread, "QEMU"); 2415 return 0; 2416 }''', dependencies: threads)) 2417config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + ''' 2418 #include <pthread.h> 2419 #include <time.h> 2420 2421 int main(void) 2422 { 2423 pthread_condattr_t attr 2424 pthread_condattr_init(&attr); 2425 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 2426 return 0; 2427 }''', dependencies: threads)) 2428config_host_data.set('CONFIG_PTHREAD_AFFINITY_NP', cc.links(gnu_source_prefix + ''' 2429 #include <pthread.h> 2430 2431 static void *f(void *p) { return NULL; } 2432 int main(void) 2433 { 2434 int setsize = CPU_ALLOC_SIZE(64); 2435 pthread_t thread; 2436 cpu_set_t *cpuset; 2437 pthread_create(&thread, 0, f, 0); 2438 cpuset = CPU_ALLOC(64); 2439 CPU_ZERO_S(setsize, cpuset); 2440 pthread_setaffinity_np(thread, setsize, cpuset); 2441 pthread_getaffinity_np(thread, setsize, cpuset); 2442 CPU_FREE(cpuset); 2443 return 0; 2444 }''', dependencies: threads)) 2445config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 2446 #include <sys/signalfd.h> 2447 #include <stddef.h> 2448 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 2449config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 2450 #include <unistd.h> 2451 #include <fcntl.h> 2452 #include <limits.h> 2453 2454 int main(void) 2455 { 2456 int len, fd = 0; 2457 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 2458 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 2459 return 0; 2460 }''')) 2461 2462config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 2463 #include <sys/mman.h> 2464 int main(void) { 2465 return mlockall(MCL_FUTURE); 2466 }''')) 2467 2468have_l2tpv3 = false 2469if get_option('l2tpv3').allowed() and have_system 2470 have_l2tpv3 = cc.has_type('struct mmsghdr', 2471 prefix: gnu_source_prefix + ''' 2472 #include <sys/socket.h> 2473 #include <linux/ip.h>''') 2474endif 2475config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2476 2477have_netmap = false 2478if get_option('netmap').allowed() and have_system 2479 have_netmap = cc.compiles(''' 2480 #include <inttypes.h> 2481 #include <net/if.h> 2482 #include <net/netmap.h> 2483 #include <net/netmap_user.h> 2484 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2485 #error 2486 #endif 2487 int main(void) { return 0; }''') 2488 if not have_netmap and get_option('netmap').enabled() 2489 error('Netmap headers not available') 2490 endif 2491endif 2492config_host_data.set('CONFIG_NETMAP', have_netmap) 2493 2494# Work around a system header bug with some kernel/XFS header 2495# versions where they both try to define 'struct fsxattr': 2496# xfs headers will not try to redefine structs from linux headers 2497# if this macro is set. 2498config_host_data.set('HAVE_FSXATTR', cc.links(''' 2499 #include <linux/fs.h> 2500 struct fsxattr foo; 2501 int main(void) { 2502 return 0; 2503 }''')) 2504 2505# Some versions of Mac OS X incorrectly define SIZE_MAX 2506config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2507 #include <stdint.h> 2508 #include <stdio.h> 2509 int main(void) { 2510 return printf("%zu", SIZE_MAX); 2511 }''', args: ['-Werror'])) 2512 2513# See if 64-bit atomic operations are supported. 2514# Note that without __atomic builtins, we can only 2515# assume atomic loads/stores max at pointer size. 2516config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 2517 #include <stdint.h> 2518 int main(void) 2519 { 2520 uint64_t x = 0, y = 0; 2521 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 2522 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 2523 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2524 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 2525 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 2526 return 0; 2527 }''')) 2528 2529has_int128 = cc.links(''' 2530 __int128_t a; 2531 __uint128_t b; 2532 int main (void) { 2533 a = a + b; 2534 b = a * b; 2535 a = a * a; 2536 return 0; 2537 }''') 2538 2539config_host_data.set('CONFIG_INT128', has_int128) 2540 2541if has_int128 2542 # "do we have 128-bit atomics which are handled inline and specifically not 2543 # via libatomic". The reason we can't use libatomic is documented in the 2544 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 2545 # We only care about these operations on 16-byte aligned pointers, so 2546 # force 16-byte alignment of the pointer, which may be greater than 2547 # __alignof(unsigned __int128) for the host. 2548 atomic_test_128 = ''' 2549 int main(int ac, char **av) { 2550 unsigned __int128 *p = __builtin_assume_aligned(av[ac - 1], sizeof(16)); 2551 p[1] = __atomic_load_n(&p[0], __ATOMIC_RELAXED); 2552 __atomic_store_n(&p[2], p[3], __ATOMIC_RELAXED); 2553 __atomic_compare_exchange_n(&p[4], &p[5], p[6], 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2554 return 0; 2555 }''' 2556 has_atomic128 = cc.links(atomic_test_128) 2557 2558 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 2559 2560 if not has_atomic128 2561 # Even with __builtin_assume_aligned, the above test may have failed 2562 # without optimization enabled. Try again with optimizations locally 2563 # enabled for the function. See 2564 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107389 2565 has_atomic128_opt = cc.links('__attribute__((optimize("O1")))' + atomic_test_128) 2566 config_host_data.set('CONFIG_ATOMIC128_OPT', has_atomic128_opt) 2567 2568 if not has_atomic128_opt 2569 config_host_data.set('CONFIG_CMPXCHG128', cc.links(''' 2570 int main(void) 2571 { 2572 unsigned __int128 x = 0, y = 0; 2573 __sync_val_compare_and_swap_16(&x, y, x); 2574 return 0; 2575 } 2576 ''')) 2577 endif 2578 endif 2579endif 2580 2581config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 2582 #include <sys/auxv.h> 2583 int main(void) { 2584 return getauxval(AT_HWCAP) == 0; 2585 }''')) 2586 2587config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 2588 #include <linux/usbdevice_fs.h> 2589 2590 #ifndef USBDEVFS_GET_CAPABILITIES 2591 #error "USBDEVFS_GET_CAPABILITIES undefined" 2592 #endif 2593 2594 #ifndef USBDEVFS_DISCONNECT_CLAIM 2595 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 2596 #endif 2597 2598 int main(void) { return 0; }''')) 2599 2600have_keyring = get_option('keyring') \ 2601 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \ 2602 .require(cc.compiles(''' 2603 #include <errno.h> 2604 #include <asm/unistd.h> 2605 #include <linux/keyctl.h> 2606 #include <sys/syscall.h> 2607 #include <unistd.h> 2608 int main(void) { 2609 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 2610 }'''), error_message: 'keyctl syscall not available on this system').allowed() 2611config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 2612 2613have_cpuid_h = cc.links(''' 2614 #include <cpuid.h> 2615 int main(void) { 2616 unsigned a, b, c, d; 2617 unsigned max = __get_cpuid_max(0, 0); 2618 2619 if (max >= 1) { 2620 __cpuid(1, a, b, c, d); 2621 } 2622 2623 if (max >= 7) { 2624 __cpuid_count(7, 0, a, b, c, d); 2625 } 2626 2627 return 0; 2628 }''') 2629config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 2630 2631config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 2632 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 2633 .require(cc.links(''' 2634 #include <cpuid.h> 2635 #include <immintrin.h> 2636 static int __attribute__((target("avx2"))) bar(void *a) { 2637 __m256i x = *(__m256i *)a; 2638 return _mm256_testz_si256(x, x); 2639 } 2640 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 2641 '''), error_message: 'AVX2 not available').allowed()) 2642 2643config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ 2644 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \ 2645 .require(cc.links(''' 2646 #include <cpuid.h> 2647 #include <immintrin.h> 2648 static int __attribute__((target("avx512f"))) bar(void *a) { 2649 __m512i x = *(__m512i *)a; 2650 return _mm512_test_epi64_mask(x, x); 2651 } 2652 int main(int argc, char *argv[]) { return bar(argv[argc - 1]); } 2653 '''), error_message: 'AVX512F not available').allowed()) 2654 2655config_host_data.set('CONFIG_AVX512BW_OPT', get_option('avx512bw') \ 2656 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512BW') \ 2657 .require(cc.links(''' 2658 #include <cpuid.h> 2659 #include <immintrin.h> 2660 static int __attribute__((target("avx512bw"))) bar(void *a) { 2661 __m512i *x = a; 2662 __m512i res= _mm512_abs_epi8(*x); 2663 return res[1]; 2664 } 2665 int main(int argc, char *argv[]) { return bar(argv[0]); } 2666 '''), error_message: 'AVX512BW not available').allowed()) 2667 2668have_pvrdma = get_option('pvrdma') \ 2669 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \ 2670 .require(cc.compiles(gnu_source_prefix + ''' 2671 #include <sys/mman.h> 2672 int main(void) 2673 { 2674 char buf = 0; 2675 void *addr = &buf; 2676 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED); 2677 2678 return 0; 2679 }'''), error_message: 'PVRDMA requires mremap').allowed() 2680 2681if have_pvrdma 2682 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links(''' 2683 #include <infiniband/verbs.h> 2684 int main(void) 2685 { 2686 struct ibv_mr *mr; 2687 struct ibv_pd *pd = NULL; 2688 size_t length = 10; 2689 uint64_t iova = 0; 2690 int access = 0; 2691 void *addr = NULL; 2692 2693 mr = ibv_reg_mr_iova(pd, addr, length, iova, access); 2694 ibv_dereg_mr(mr); 2695 return 0; 2696 }''')) 2697endif 2698 2699if get_option('membarrier').disabled() 2700 have_membarrier = false 2701elif targetos == 'windows' 2702 have_membarrier = true 2703elif targetos == 'linux' 2704 have_membarrier = cc.compiles(''' 2705 #include <linux/membarrier.h> 2706 #include <sys/syscall.h> 2707 #include <unistd.h> 2708 #include <stdlib.h> 2709 int main(void) { 2710 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 2711 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 2712 exit(0); 2713 }''') 2714endif 2715config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 2716 .require(have_membarrier, error_message: 'membarrier system call not available') \ 2717 .allowed()) 2718 2719have_afalg = get_option('crypto_afalg') \ 2720 .require(cc.compiles(gnu_source_prefix + ''' 2721 #include <errno.h> 2722 #include <sys/types.h> 2723 #include <sys/socket.h> 2724 #include <linux/if_alg.h> 2725 int main(void) { 2726 int sock; 2727 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 2728 return sock; 2729 } 2730 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 2731config_host_data.set('CONFIG_AF_ALG', have_afalg) 2732 2733config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 2734 'linux/vm_sockets.h', 'AF_VSOCK', 2735 prefix: '#include <sys/socket.h>', 2736)) 2737 2738have_vss = false 2739have_vss_sdk = false # old xp/2003 SDK 2740if targetos == 'windows' and link_language == 'cpp' 2741 have_vss = cxx.compiles(''' 2742 #define __MIDL_user_allocate_free_DEFINED__ 2743 #include <vss.h> 2744 int main(void) { return VSS_CTX_BACKUP; }''') 2745 have_vss_sdk = cxx.has_header('vscoordint.h') 2746endif 2747config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 2748 2749foreach k, v: config_host 2750 if k.startswith('CONFIG_') 2751 config_host_data.set(k, v == 'y' ? 1 : v) 2752 endif 2753endforeach 2754 2755# Older versions of MinGW do not import _lock_file and _unlock_file properly. 2756# This was fixed for v6.0.0 with commit b48e3ac8969d. 2757if targetos == 'windows' 2758 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 2759 #include <stdio.h> 2760 int main(void) { 2761 _lock_file(NULL); 2762 _unlock_file(NULL); 2763 return 0; 2764 }''', name: '_lock_file and _unlock_file')) 2765endif 2766 2767if targetos == 'windows' 2768 mingw_has_setjmp_longjmp = cc.links(''' 2769 #include <setjmp.h> 2770 int main(void) { 2771 /* 2772 * These functions are not available in setjmp header, but may be 2773 * available at link time, from libmingwex.a. 2774 */ 2775 extern int __mingw_setjmp(jmp_buf); 2776 extern void __attribute__((noreturn)) __mingw_longjmp(jmp_buf, int); 2777 jmp_buf env; 2778 __mingw_setjmp(env); 2779 __mingw_longjmp(env, 0); 2780 } 2781 ''', name: 'mingw setjmp and longjmp') 2782 2783 if cpu == 'aarch64' and not mingw_has_setjmp_longjmp 2784 error('mingw must provide setjmp/longjmp for windows-arm64') 2785 endif 2786endif 2787 2788######################## 2789# Target configuration # 2790######################## 2791 2792minikconf = find_program('scripts/minikconf.py') 2793config_all = {} 2794config_all_devices = {} 2795config_all_disas = {} 2796config_devices_mak_list = [] 2797config_devices_h = {} 2798config_target_h = {} 2799config_target_mak = {} 2800 2801disassemblers = { 2802 'alpha' : ['CONFIG_ALPHA_DIS'], 2803 'avr' : ['CONFIG_AVR_DIS'], 2804 'cris' : ['CONFIG_CRIS_DIS'], 2805 'hexagon' : ['CONFIG_HEXAGON_DIS'], 2806 'hppa' : ['CONFIG_HPPA_DIS'], 2807 'i386' : ['CONFIG_I386_DIS'], 2808 'x86_64' : ['CONFIG_I386_DIS'], 2809 'm68k' : ['CONFIG_M68K_DIS'], 2810 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 2811 'mips' : ['CONFIG_MIPS_DIS'], 2812 'nios2' : ['CONFIG_NIOS2_DIS'], 2813 'or1k' : ['CONFIG_OPENRISC_DIS'], 2814 'ppc' : ['CONFIG_PPC_DIS'], 2815 'riscv' : ['CONFIG_RISCV_DIS'], 2816 'rx' : ['CONFIG_RX_DIS'], 2817 's390' : ['CONFIG_S390_DIS'], 2818 'sh4' : ['CONFIG_SH4_DIS'], 2819 'sparc' : ['CONFIG_SPARC_DIS'], 2820 'xtensa' : ['CONFIG_XTENSA_DIS'], 2821 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 2822} 2823 2824have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 2825host_kconfig = \ 2826 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 2827 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 2828 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 2829 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 2830 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 2831 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 2832 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 2833 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 2834 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 2835 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 2836 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ 2837 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \ 2838 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 2839 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) 2840 2841ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 2842 2843default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 2844actual_target_dirs = [] 2845fdt_required = [] 2846foreach target : target_dirs 2847 config_target = { 'TARGET_NAME': target.split('-')[0] } 2848 if target.endswith('linux-user') 2849 if targetos != 'linux' 2850 if default_targets 2851 continue 2852 endif 2853 error('Target @0@ is only available on a Linux host'.format(target)) 2854 endif 2855 config_target += { 'CONFIG_LINUX_USER': 'y' } 2856 elif target.endswith('bsd-user') 2857 if 'CONFIG_BSD' not in config_host 2858 if default_targets 2859 continue 2860 endif 2861 error('Target @0@ is only available on a BSD host'.format(target)) 2862 endif 2863 config_target += { 'CONFIG_BSD_USER': 'y' } 2864 elif target.endswith('softmmu') 2865 config_target += { 'CONFIG_SOFTMMU': 'y' } 2866 endif 2867 if target.endswith('-user') 2868 config_target += { 2869 'CONFIG_USER_ONLY': 'y', 2870 'CONFIG_QEMU_INTERP_PREFIX': 2871 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']) 2872 } 2873 endif 2874 2875 accel_kconfig = [] 2876 foreach sym: accelerators 2877 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 2878 config_target += { sym: 'y' } 2879 config_all += { sym: 'y' } 2880 if target in modular_tcg 2881 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 2882 else 2883 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 2884 endif 2885 accel_kconfig += [ sym + '=y' ] 2886 endif 2887 endforeach 2888 if accel_kconfig.length() == 0 2889 if default_targets 2890 continue 2891 endif 2892 error('No accelerator available for target @0@'.format(target)) 2893 endif 2894 2895 actual_target_dirs += target 2896 config_target += keyval.load('configs/targets' / target + '.mak') 2897 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 2898 2899 if 'TARGET_NEED_FDT' in config_target 2900 fdt_required += target 2901 endif 2902 2903 # Add default keys 2904 if 'TARGET_BASE_ARCH' not in config_target 2905 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 2906 endif 2907 if 'TARGET_ABI_DIR' not in config_target 2908 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 2909 endif 2910 if 'TARGET_BIG_ENDIAN' not in config_target 2911 config_target += {'TARGET_BIG_ENDIAN': 'n'} 2912 endif 2913 2914 foreach k, v: disassemblers 2915 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 2916 foreach sym: v 2917 config_target += { sym: 'y' } 2918 config_all_disas += { sym: 'y' } 2919 endforeach 2920 endif 2921 endforeach 2922 2923 config_target_data = configuration_data() 2924 foreach k, v: config_target 2925 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 2926 # do nothing 2927 elif ignored.contains(k) 2928 # do nothing 2929 elif k == 'TARGET_BASE_ARCH' 2930 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 2931 # not used to select files from sourcesets. 2932 config_target_data.set('TARGET_' + v.to_upper(), 1) 2933 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 2934 config_target_data.set_quoted(k, v) 2935 elif v == 'y' 2936 config_target_data.set(k, 1) 2937 elif v == 'n' 2938 config_target_data.set(k, 0) 2939 else 2940 config_target_data.set(k, v) 2941 endif 2942 endforeach 2943 config_target_data.set('QEMU_ARCH', 2944 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 2945 config_target_h += {target: configure_file(output: target + '-config-target.h', 2946 configuration: config_target_data)} 2947 2948 if target.endswith('-softmmu') 2949 config_input = meson.get_external_property(target, 'default') 2950 config_devices_mak = target + '-config-devices.mak' 2951 config_devices_mak = configure_file( 2952 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 2953 output: config_devices_mak, 2954 depfile: config_devices_mak + '.d', 2955 capture: true, 2956 command: [minikconf, 2957 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 2958 config_devices_mak, '@DEPFILE@', '@INPUT@', 2959 host_kconfig, accel_kconfig, 2960 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y']) 2961 2962 config_devices_data = configuration_data() 2963 config_devices = keyval.load(config_devices_mak) 2964 foreach k, v: config_devices 2965 config_devices_data.set(k, 1) 2966 endforeach 2967 config_devices_mak_list += config_devices_mak 2968 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 2969 configuration: config_devices_data)} 2970 config_target += config_devices 2971 config_all_devices += config_devices 2972 endif 2973 config_target_mak += {target: config_target} 2974endforeach 2975target_dirs = actual_target_dirs 2976 2977# This configuration is used to build files that are shared by 2978# multiple binaries, and then extracted out of the "common" 2979# static_library target. 2980# 2981# We do not use all_sources()/all_dependencies(), because it would 2982# build literally all source files, including devices only used by 2983# targets that are not built for this compilation. The CONFIG_ALL 2984# pseudo symbol replaces it. 2985 2986config_all += config_all_devices 2987config_all += config_host 2988config_all += config_all_disas 2989config_all += { 2990 'CONFIG_XEN': xen.found(), 2991 'CONFIG_SOFTMMU': have_system, 2992 'CONFIG_USER_ONLY': have_user, 2993 'CONFIG_ALL': true, 2994} 2995 2996target_configs_h = [] 2997foreach target: target_dirs 2998 target_configs_h += config_target_h[target] 2999 target_configs_h += config_devices_h.get(target, []) 3000endforeach 3001genh += custom_target('config-poison.h', 3002 input: [target_configs_h], 3003 output: 'config-poison.h', 3004 capture: true, 3005 command: [find_program('scripts/make-config-poison.sh'), 3006 target_configs_h]) 3007 3008############## 3009# Submodules # 3010############## 3011 3012capstone = not_found 3013if not get_option('capstone').auto() or have_system or have_user 3014 capstone = dependency('capstone', version: '>=3.0.5', 3015 method: 'pkg-config', 3016 required: get_option('capstone')) 3017 3018 # Some versions of capstone have broken pkg-config file 3019 # that reports a wrong -I path, causing the #include to 3020 # fail later. If the system has such a broken version 3021 # do not use it. 3022 if capstone.found() and not cc.compiles('#include <capstone.h>', 3023 dependencies: [capstone]) 3024 capstone = not_found 3025 if get_option('capstone').enabled() 3026 error('capstone requested, but it does not appear to work') 3027 endif 3028 endif 3029endif 3030 3031libvfio_user_dep = not_found 3032if have_system and vfio_user_server_allowed 3033 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build') 3034 3035 if not have_internal 3036 error('libvfio-user source not found - please pull git submodule') 3037 endif 3038 3039 libvfio_user_proj = subproject('libvfio-user') 3040 3041 libvfio_user_dep = libvfio_user_proj.get_variable('libvfio_user_dep') 3042endif 3043 3044fdt = not_found 3045if have_system 3046 fdt_opt = get_option('fdt') 3047 if fdt_opt in ['enabled', 'auto', 'system'] 3048 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') 3049 fdt = cc.find_library('fdt', 3050 required: fdt_opt == 'system' or 3051 fdt_opt == 'enabled' and not have_internal) 3052 if fdt.found() and cc.links(''' 3053 #include <libfdt.h> 3054 #include <libfdt_env.h> 3055 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''', 3056 dependencies: fdt) 3057 fdt_opt = 'system' 3058 elif fdt_opt == 'system' 3059 error('system libfdt requested, but it is too old (1.5.1 or newer required)') 3060 elif have_internal 3061 fdt_opt = 'internal' 3062 else 3063 fdt_opt = 'disabled' 3064 fdt = not_found 3065 endif 3066 endif 3067 if fdt_opt == 'internal' 3068 fdt_files = files( 3069 'dtc/libfdt/fdt.c', 3070 'dtc/libfdt/fdt_ro.c', 3071 'dtc/libfdt/fdt_wip.c', 3072 'dtc/libfdt/fdt_sw.c', 3073 'dtc/libfdt/fdt_rw.c', 3074 'dtc/libfdt/fdt_strerror.c', 3075 'dtc/libfdt/fdt_empty_tree.c', 3076 'dtc/libfdt/fdt_addresses.c', 3077 'dtc/libfdt/fdt_overlay.c', 3078 'dtc/libfdt/fdt_check.c', 3079 ) 3080 3081 fdt_inc = include_directories('dtc/libfdt') 3082 libfdt = static_library('fdt', 3083 build_by_default: false, 3084 sources: fdt_files, 3085 include_directories: fdt_inc) 3086 fdt = declare_dependency(link_with: libfdt, 3087 include_directories: fdt_inc) 3088 endif 3089else 3090 fdt_opt = 'disabled' 3091endif 3092if not fdt.found() and fdt_required.length() > 0 3093 error('fdt not available but required by targets ' + ', '.join(fdt_required)) 3094endif 3095 3096config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 3097config_host_data.set('CONFIG_FDT', fdt.found()) 3098config_host_data.set('CONFIG_SLIRP', slirp.found()) 3099 3100##################### 3101# Generated sources # 3102##################### 3103 3104genh += configure_file(output: 'config-host.h', configuration: config_host_data) 3105 3106hxtool = find_program('scripts/hxtool') 3107shaderinclude = find_program('scripts/shaderinclude.py') 3108qapi_gen = find_program('scripts/qapi-gen.py') 3109qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 3110 meson.current_source_dir() / 'scripts/qapi/commands.py', 3111 meson.current_source_dir() / 'scripts/qapi/common.py', 3112 meson.current_source_dir() / 'scripts/qapi/error.py', 3113 meson.current_source_dir() / 'scripts/qapi/events.py', 3114 meson.current_source_dir() / 'scripts/qapi/expr.py', 3115 meson.current_source_dir() / 'scripts/qapi/gen.py', 3116 meson.current_source_dir() / 'scripts/qapi/introspect.py', 3117 meson.current_source_dir() / 'scripts/qapi/main.py', 3118 meson.current_source_dir() / 'scripts/qapi/parser.py', 3119 meson.current_source_dir() / 'scripts/qapi/schema.py', 3120 meson.current_source_dir() / 'scripts/qapi/source.py', 3121 meson.current_source_dir() / 'scripts/qapi/types.py', 3122 meson.current_source_dir() / 'scripts/qapi/visit.py', 3123 meson.current_source_dir() / 'scripts/qapi-gen.py' 3124] 3125 3126tracetool = [ 3127 python, files('scripts/tracetool.py'), 3128 '--backend=' + ','.join(get_option('trace_backends')) 3129] 3130tracetool_depends = files( 3131 'scripts/tracetool/backend/log.py', 3132 'scripts/tracetool/backend/__init__.py', 3133 'scripts/tracetool/backend/dtrace.py', 3134 'scripts/tracetool/backend/ftrace.py', 3135 'scripts/tracetool/backend/simple.py', 3136 'scripts/tracetool/backend/syslog.py', 3137 'scripts/tracetool/backend/ust.py', 3138 'scripts/tracetool/format/ust_events_c.py', 3139 'scripts/tracetool/format/ust_events_h.py', 3140 'scripts/tracetool/format/__init__.py', 3141 'scripts/tracetool/format/d.py', 3142 'scripts/tracetool/format/simpletrace_stap.py', 3143 'scripts/tracetool/format/c.py', 3144 'scripts/tracetool/format/h.py', 3145 'scripts/tracetool/format/log_stap.py', 3146 'scripts/tracetool/format/stap.py', 3147 'scripts/tracetool/__init__.py', 3148 'scripts/tracetool/vcpu.py' 3149) 3150 3151qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 3152 meson.current_source_dir(), 3153 get_option('pkgversion'), meson.project_version()] 3154qemu_version = custom_target('qemu-version.h', 3155 output: 'qemu-version.h', 3156 command: qemu_version_cmd, 3157 capture: true, 3158 build_by_default: true, 3159 build_always_stale: true) 3160genh += qemu_version 3161 3162hxdep = [] 3163hx_headers = [ 3164 ['qemu-options.hx', 'qemu-options.def'], 3165 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 3166] 3167if have_system 3168 hx_headers += [ 3169 ['hmp-commands.hx', 'hmp-commands.h'], 3170 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 3171 ] 3172endif 3173foreach d : hx_headers 3174 hxdep += custom_target(d[1], 3175 input: files(d[0]), 3176 output: d[1], 3177 capture: true, 3178 build_by_default: true, # to be removed when added to a target 3179 command: [hxtool, '-h', '@INPUT0@']) 3180endforeach 3181genh += hxdep 3182 3183################### 3184# Collect sources # 3185################### 3186 3187authz_ss = ss.source_set() 3188blockdev_ss = ss.source_set() 3189block_ss = ss.source_set() 3190chardev_ss = ss.source_set() 3191common_ss = ss.source_set() 3192crypto_ss = ss.source_set() 3193hwcore_ss = ss.source_set() 3194io_ss = ss.source_set() 3195qmp_ss = ss.source_set() 3196qom_ss = ss.source_set() 3197softmmu_ss = ss.source_set() 3198specific_fuzz_ss = ss.source_set() 3199specific_ss = ss.source_set() 3200stub_ss = ss.source_set() 3201trace_ss = ss.source_set() 3202user_ss = ss.source_set() 3203util_ss = ss.source_set() 3204 3205# accel modules 3206qtest_module_ss = ss.source_set() 3207tcg_module_ss = ss.source_set() 3208 3209modules = {} 3210target_modules = {} 3211hw_arch = {} 3212target_arch = {} 3213target_softmmu_arch = {} 3214target_user_arch = {} 3215 3216############### 3217# Trace files # 3218############### 3219 3220# TODO: add each directory to the subdirs from its own meson.build, once 3221# we have those 3222trace_events_subdirs = [ 3223 'crypto', 3224 'qapi', 3225 'qom', 3226 'monitor', 3227 'util', 3228 'gdbstub', 3229] 3230if have_linux_user 3231 trace_events_subdirs += [ 'linux-user' ] 3232endif 3233if have_bsd_user 3234 trace_events_subdirs += [ 'bsd-user' ] 3235endif 3236if have_block 3237 trace_events_subdirs += [ 3238 'authz', 3239 'block', 3240 'io', 3241 'nbd', 3242 'scsi', 3243 ] 3244endif 3245if have_system 3246 trace_events_subdirs += [ 3247 'accel/kvm', 3248 'audio', 3249 'backends', 3250 'backends/tpm', 3251 'chardev', 3252 'ebpf', 3253 'hw/9pfs', 3254 'hw/acpi', 3255 'hw/adc', 3256 'hw/alpha', 3257 'hw/arm', 3258 'hw/audio', 3259 'hw/block', 3260 'hw/block/dataplane', 3261 'hw/char', 3262 'hw/display', 3263 'hw/dma', 3264 'hw/hyperv', 3265 'hw/i2c', 3266 'hw/i386', 3267 'hw/i386/xen', 3268 'hw/i386/kvm', 3269 'hw/ide', 3270 'hw/input', 3271 'hw/intc', 3272 'hw/isa', 3273 'hw/mem', 3274 'hw/mips', 3275 'hw/misc', 3276 'hw/misc/macio', 3277 'hw/net', 3278 'hw/net/can', 3279 'hw/nubus', 3280 'hw/nvme', 3281 'hw/nvram', 3282 'hw/pci', 3283 'hw/pci-host', 3284 'hw/ppc', 3285 'hw/rdma', 3286 'hw/rdma/vmw', 3287 'hw/rtc', 3288 'hw/s390x', 3289 'hw/scsi', 3290 'hw/sd', 3291 'hw/sh4', 3292 'hw/sparc', 3293 'hw/sparc64', 3294 'hw/ssi', 3295 'hw/timer', 3296 'hw/tpm', 3297 'hw/usb', 3298 'hw/vfio', 3299 'hw/virtio', 3300 'hw/watchdog', 3301 'hw/xen', 3302 'hw/gpio', 3303 'migration', 3304 'net', 3305 'softmmu', 3306 'ui', 3307 'hw/remote', 3308 ] 3309endif 3310if have_system or have_user 3311 trace_events_subdirs += [ 3312 'accel/tcg', 3313 'hw/core', 3314 'target/arm', 3315 'target/arm/hvf', 3316 'target/hppa', 3317 'target/i386', 3318 'target/i386/kvm', 3319 'target/mips/tcg', 3320 'target/nios2', 3321 'target/ppc', 3322 'target/riscv', 3323 'target/s390x', 3324 'target/s390x/kvm', 3325 'target/sparc', 3326 ] 3327endif 3328 3329vhost_user = not_found 3330if targetos == 'linux' and have_vhost_user 3331 libvhost_user = subproject('libvhost-user') 3332 vhost_user = libvhost_user.get_variable('vhost_user_dep') 3333endif 3334 3335libvduse = not_found 3336if have_libvduse 3337 libvduse_proj = subproject('libvduse') 3338 libvduse = libvduse_proj.get_variable('libvduse_dep') 3339endif 3340 3341# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 3342# that is filled in by qapi/. 3343subdir('qapi') 3344subdir('qobject') 3345subdir('stubs') 3346subdir('trace') 3347subdir('util') 3348subdir('qom') 3349subdir('authz') 3350subdir('crypto') 3351subdir('ui') 3352subdir('hw') 3353subdir('gdbstub') 3354 3355if enable_modules 3356 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3357 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 3358endif 3359 3360qom_ss = qom_ss.apply(config_host, strict: false) 3361libqom = static_library('qom', qom_ss.sources() + genh, 3362 dependencies: [qom_ss.dependencies()], 3363 name_suffix: 'fa') 3364qom = declare_dependency(link_whole: libqom) 3365 3366event_loop_base = files('event-loop-base.c') 3367event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh, 3368 build_by_default: true) 3369event_loop_base = declare_dependency(link_whole: event_loop_base, 3370 dependencies: [qom]) 3371 3372stub_ss = stub_ss.apply(config_all, strict: false) 3373 3374util_ss.add_all(trace_ss) 3375util_ss = util_ss.apply(config_all, strict: false) 3376libqemuutil = static_library('qemuutil', 3377 sources: util_ss.sources() + stub_ss.sources() + genh, 3378 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman]) 3379qemuutil = declare_dependency(link_with: libqemuutil, 3380 sources: genh + version_res, 3381 dependencies: [event_loop_base]) 3382 3383if have_system or have_user 3384 decodetree = generator(find_program('scripts/decodetree.py'), 3385 output: 'decode-@BASENAME@.c.inc', 3386 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3387 subdir('libdecnumber') 3388 subdir('target') 3389endif 3390 3391subdir('audio') 3392subdir('io') 3393subdir('chardev') 3394subdir('fsdev') 3395subdir('dump') 3396 3397if have_block 3398 block_ss.add(files( 3399 'block.c', 3400 'blockjob.c', 3401 'job.c', 3402 'qemu-io-cmds.c', 3403 )) 3404 if config_host_data.get('CONFIG_REPLICATION') 3405 block_ss.add(files('replication.c')) 3406 endif 3407 3408 subdir('nbd') 3409 subdir('scsi') 3410 subdir('block') 3411 3412 blockdev_ss.add(files( 3413 'blockdev.c', 3414 'blockdev-nbd.c', 3415 'iothread.c', 3416 'job-qmp.c', 3417 ), gnutls) 3418 3419 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3420 # os-win32.c does not 3421 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 3422 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 3423endif 3424 3425common_ss.add(files('cpus-common.c')) 3426specific_ss.add(files('cpu.c')) 3427 3428subdir('softmmu') 3429 3430# Work around a gcc bug/misfeature wherein constant propagation looks 3431# through an alias: 3432# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3433# to guess that a const variable is always zero. Without lto, this is 3434# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3435# without lto, not even the alias is required -- we simply use different 3436# declarations in different compilation units. 3437pagevary = files('page-vary-common.c') 3438if get_option('b_lto') 3439 pagevary_flags = ['-fno-lto'] 3440 if get_option('cfi') 3441 pagevary_flags += '-fno-sanitize=cfi-icall' 3442 endif 3443 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3444 c_args: pagevary_flags) 3445 pagevary = declare_dependency(link_with: pagevary) 3446endif 3447common_ss.add(pagevary) 3448specific_ss.add(files('page-vary.c')) 3449 3450subdir('backends') 3451subdir('disas') 3452subdir('migration') 3453subdir('monitor') 3454subdir('net') 3455subdir('replay') 3456subdir('semihosting') 3457subdir('stats') 3458subdir('tcg') 3459subdir('fpu') 3460subdir('accel') 3461subdir('plugins') 3462subdir('ebpf') 3463 3464common_user_inc = [] 3465 3466subdir('common-user') 3467subdir('bsd-user') 3468subdir('linux-user') 3469 3470# needed for fuzzing binaries 3471subdir('tests/qtest/libqos') 3472subdir('tests/qtest/fuzz') 3473 3474# accel modules 3475tcg_real_module_ss = ss.source_set() 3476tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3477specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3478target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3479 'tcg': tcg_real_module_ss }} 3480 3481######################## 3482# Library dependencies # 3483######################## 3484 3485modinfo_collect = find_program('scripts/modinfo-collect.py') 3486modinfo_generate = find_program('scripts/modinfo-generate.py') 3487modinfo_files = [] 3488 3489block_mods = [] 3490softmmu_mods = [] 3491foreach d, list : modules 3492 if not (d == 'block' ? have_block : have_system) 3493 continue 3494 endif 3495 3496 foreach m, module_ss : list 3497 if enable_modules 3498 module_ss = module_ss.apply(config_all, strict: false) 3499 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3500 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 3501 if d == 'block' 3502 block_mods += sl 3503 else 3504 softmmu_mods += sl 3505 endif 3506 if module_ss.sources() != [] 3507 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3508 # input. Sources can be used multiple times but objects are 3509 # unique when it comes to lookup in compile_commands.json. 3510 # Depnds on a mesion version with 3511 # https://github.com/mesonbuild/meson/pull/8900 3512 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3513 output: d + '-' + m + '.modinfo', 3514 input: module_ss.sources() + genh, 3515 capture: true, 3516 command: [modinfo_collect, module_ss.sources()]) 3517 endif 3518 else 3519 if d == 'block' 3520 block_ss.add_all(module_ss) 3521 else 3522 softmmu_ss.add_all(module_ss) 3523 endif 3524 endif 3525 endforeach 3526endforeach 3527 3528foreach d, list : target_modules 3529 foreach m, module_ss : list 3530 if enable_modules 3531 foreach target : target_dirs 3532 if target.endswith('-softmmu') 3533 config_target = config_target_mak[target] 3534 config_target += config_host 3535 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3536 c_args = ['-DNEED_CPU_H', 3537 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3538 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3539 target_module_ss = module_ss.apply(config_target, strict: false) 3540 if target_module_ss.sources() != [] 3541 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3542 sl = static_library(module_name, 3543 [genh, target_module_ss.sources()], 3544 dependencies: [modulecommon, target_module_ss.dependencies()], 3545 include_directories: target_inc, 3546 c_args: c_args, 3547 pic: true) 3548 softmmu_mods += sl 3549 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3550 modinfo_files += custom_target(module_name + '.modinfo', 3551 output: module_name + '.modinfo', 3552 input: target_module_ss.sources() + genh, 3553 capture: true, 3554 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3555 endif 3556 endif 3557 endforeach 3558 else 3559 specific_ss.add_all(module_ss) 3560 endif 3561 endforeach 3562endforeach 3563 3564if enable_modules 3565 foreach target : target_dirs 3566 if target.endswith('-softmmu') 3567 config_target = config_target_mak[target] 3568 config_devices_mak = target + '-config-devices.mak' 3569 modinfo_src = custom_target('modinfo-' + target + '.c', 3570 output: 'modinfo-' + target + '.c', 3571 input: modinfo_files, 3572 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3573 capture: true) 3574 3575 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3576 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3577 3578 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3579 hw_arch[arch].add(modinfo_dep) 3580 endif 3581 endforeach 3582endif 3583 3584nm = find_program('nm') 3585undefsym = find_program('scripts/undefsym.py') 3586block_syms = custom_target('block.syms', output: 'block.syms', 3587 input: [libqemuutil, block_mods], 3588 capture: true, 3589 command: [undefsym, nm, '@INPUT@']) 3590qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3591 input: [libqemuutil, softmmu_mods], 3592 capture: true, 3593 command: [undefsym, nm, '@INPUT@']) 3594 3595authz_ss = authz_ss.apply(config_host, strict: false) 3596libauthz = static_library('authz', authz_ss.sources() + genh, 3597 dependencies: [authz_ss.dependencies()], 3598 name_suffix: 'fa', 3599 build_by_default: false) 3600 3601authz = declare_dependency(link_whole: libauthz, 3602 dependencies: qom) 3603 3604crypto_ss = crypto_ss.apply(config_host, strict: false) 3605libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3606 dependencies: [crypto_ss.dependencies()], 3607 name_suffix: 'fa', 3608 build_by_default: false) 3609 3610crypto = declare_dependency(link_whole: libcrypto, 3611 dependencies: [authz, qom]) 3612 3613io_ss = io_ss.apply(config_host, strict: false) 3614libio = static_library('io', io_ss.sources() + genh, 3615 dependencies: [io_ss.dependencies()], 3616 link_with: libqemuutil, 3617 name_suffix: 'fa', 3618 build_by_default: false) 3619 3620io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 3621 3622libmigration = static_library('migration', sources: migration_files + genh, 3623 name_suffix: 'fa', 3624 build_by_default: false) 3625migration = declare_dependency(link_with: libmigration, 3626 dependencies: [zlib, qom, io]) 3627softmmu_ss.add(migration) 3628 3629block_ss = block_ss.apply(config_host, strict: false) 3630libblock = static_library('block', block_ss.sources() + genh, 3631 dependencies: block_ss.dependencies(), 3632 link_depends: block_syms, 3633 name_suffix: 'fa', 3634 build_by_default: false) 3635 3636block = declare_dependency(link_whole: [libblock], 3637 link_args: '@block.syms', 3638 dependencies: [crypto, io]) 3639 3640blockdev_ss = blockdev_ss.apply(config_host, strict: false) 3641libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3642 dependencies: blockdev_ss.dependencies(), 3643 name_suffix: 'fa', 3644 build_by_default: false) 3645 3646blockdev = declare_dependency(link_whole: [libblockdev], 3647 dependencies: [block, event_loop_base]) 3648 3649qmp_ss = qmp_ss.apply(config_host, strict: false) 3650libqmp = static_library('qmp', qmp_ss.sources() + genh, 3651 dependencies: qmp_ss.dependencies(), 3652 name_suffix: 'fa', 3653 build_by_default: false) 3654 3655qmp = declare_dependency(link_whole: [libqmp]) 3656 3657libchardev = static_library('chardev', chardev_ss.sources() + genh, 3658 name_suffix: 'fa', 3659 dependencies: chardev_ss.dependencies(), 3660 build_by_default: false) 3661 3662chardev = declare_dependency(link_whole: libchardev) 3663 3664hwcore_ss = hwcore_ss.apply(config_host, strict: false) 3665libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3666 name_suffix: 'fa', 3667 build_by_default: false) 3668hwcore = declare_dependency(link_whole: libhwcore) 3669common_ss.add(hwcore) 3670 3671########### 3672# Targets # 3673########### 3674 3675emulator_modules = [] 3676foreach m : block_mods + softmmu_mods 3677 emulator_modules += shared_module(m.name(), 3678 build_by_default: true, 3679 name_prefix: '', 3680 link_whole: m, 3681 install: true, 3682 install_dir: qemu_moddir) 3683endforeach 3684if emulator_modules.length() > 0 3685 alias_target('modules', emulator_modules) 3686endif 3687 3688softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3689common_ss.add(qom, qemuutil) 3690 3691common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 3692common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3693 3694common_all = common_ss.apply(config_all, strict: false) 3695common_all = static_library('common', 3696 build_by_default: false, 3697 sources: common_all.sources() + genh, 3698 include_directories: common_user_inc, 3699 implicit_include_directories: false, 3700 dependencies: common_all.dependencies(), 3701 name_suffix: 'fa') 3702 3703feature_to_c = find_program('scripts/feature_to_c.sh') 3704 3705if targetos == 'darwin' 3706 entitlement = find_program('scripts/entitlement.sh') 3707endif 3708 3709emulators = {} 3710foreach target : target_dirs 3711 config_target = config_target_mak[target] 3712 target_name = config_target['TARGET_NAME'] 3713 target_base_arch = config_target['TARGET_BASE_ARCH'] 3714 arch_srcs = [config_target_h[target]] 3715 arch_deps = [] 3716 c_args = ['-DNEED_CPU_H', 3717 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3718 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3719 link_args = emulator_link_args 3720 3721 config_target += config_host 3722 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3723 if targetos == 'linux' 3724 target_inc += include_directories('linux-headers', is_system: true) 3725 endif 3726 if target.endswith('-softmmu') 3727 target_type='system' 3728 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false) 3729 arch_srcs += t.sources() 3730 arch_deps += t.dependencies() 3731 3732 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3733 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3734 arch_srcs += hw.sources() 3735 arch_deps += hw.dependencies() 3736 3737 arch_srcs += config_devices_h[target] 3738 link_args += ['@block.syms', '@qemu.syms'] 3739 else 3740 abi = config_target['TARGET_ABI_DIR'] 3741 target_type='user' 3742 target_inc += common_user_inc 3743 if target_base_arch in target_user_arch 3744 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3745 arch_srcs += t.sources() 3746 arch_deps += t.dependencies() 3747 endif 3748 if 'CONFIG_LINUX_USER' in config_target 3749 base_dir = 'linux-user' 3750 endif 3751 if 'CONFIG_BSD_USER' in config_target 3752 base_dir = 'bsd-user' 3753 target_inc += include_directories('bsd-user/' / targetos) 3754 target_inc += include_directories('bsd-user/host/' / host_arch) 3755 dir = base_dir / abi 3756 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3757 endif 3758 target_inc += include_directories( 3759 base_dir, 3760 base_dir / abi, 3761 ) 3762 if 'CONFIG_LINUX_USER' in config_target 3763 dir = base_dir / abi 3764 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3765 if config_target.has_key('TARGET_SYSTBL_ABI') 3766 arch_srcs += \ 3767 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3768 extra_args : config_target['TARGET_SYSTBL_ABI']) 3769 endif 3770 endif 3771 endif 3772 3773 if 'TARGET_XML_FILES' in config_target 3774 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3775 output: target + '-gdbstub-xml.c', 3776 input: files(config_target['TARGET_XML_FILES'].split()), 3777 command: [feature_to_c, '@INPUT@'], 3778 capture: true) 3779 arch_srcs += gdbstub_xml 3780 endif 3781 3782 t = target_arch[target_base_arch].apply(config_target, strict: false) 3783 arch_srcs += t.sources() 3784 arch_deps += t.dependencies() 3785 3786 target_common = common_ss.apply(config_target, strict: false) 3787 objects = common_all.extract_objects(target_common.sources()) 3788 deps = target_common.dependencies() 3789 3790 target_specific = specific_ss.apply(config_target, strict: false) 3791 arch_srcs += target_specific.sources() 3792 arch_deps += target_specific.dependencies() 3793 3794 lib = static_library('qemu-' + target, 3795 sources: arch_srcs + genh, 3796 dependencies: arch_deps, 3797 objects: objects, 3798 include_directories: target_inc, 3799 c_args: c_args, 3800 build_by_default: false, 3801 name_suffix: 'fa') 3802 3803 if target.endswith('-softmmu') 3804 execs = [{ 3805 'name': 'qemu-system-' + target_name, 3806 'win_subsystem': 'console', 3807 'sources': files('softmmu/main.c'), 3808 'dependencies': [] 3809 }] 3810 if targetos == 'windows' and (sdl.found() or gtk.found()) 3811 execs += [{ 3812 'name': 'qemu-system-' + target_name + 'w', 3813 'win_subsystem': 'windows', 3814 'sources': files('softmmu/main.c'), 3815 'dependencies': [] 3816 }] 3817 endif 3818 if get_option('fuzzing') 3819 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 3820 execs += [{ 3821 'name': 'qemu-fuzz-' + target_name, 3822 'win_subsystem': 'console', 3823 'sources': specific_fuzz.sources(), 3824 'dependencies': specific_fuzz.dependencies(), 3825 }] 3826 endif 3827 else 3828 execs = [{ 3829 'name': 'qemu-' + target_name, 3830 'win_subsystem': 'console', 3831 'sources': [], 3832 'dependencies': [] 3833 }] 3834 endif 3835 foreach exe: execs 3836 exe_name = exe['name'] 3837 if targetos == 'darwin' 3838 exe_name += '-unsigned' 3839 endif 3840 3841 emulator = executable(exe_name, exe['sources'], 3842 install: true, 3843 c_args: c_args, 3844 dependencies: arch_deps + deps + exe['dependencies'], 3845 objects: lib.extract_all_objects(recursive: true), 3846 link_language: link_language, 3847 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 3848 link_args: link_args, 3849 win_subsystem: exe['win_subsystem']) 3850 3851 if targetos == 'darwin' 3852 icon = 'pc-bios/qemu.rsrc' 3853 build_input = [emulator, files(icon)] 3854 install_input = [ 3855 get_option('bindir') / exe_name, 3856 meson.current_source_dir() / icon 3857 ] 3858 if 'CONFIG_HVF' in config_target 3859 entitlements = 'accel/hvf/entitlements.plist' 3860 build_input += files(entitlements) 3861 install_input += meson.current_source_dir() / entitlements 3862 endif 3863 3864 emulators += {exe['name'] : custom_target(exe['name'], 3865 input: build_input, 3866 output: exe['name'], 3867 command: [entitlement, '@OUTPUT@', '@INPUT@']) 3868 } 3869 3870 meson.add_install_script(entitlement, '--install', 3871 get_option('bindir') / exe['name'], 3872 install_input) 3873 else 3874 emulators += {exe['name']: emulator} 3875 endif 3876 3877 if stap.found() 3878 foreach stp: [ 3879 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 3880 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 3881 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 3882 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 3883 ] 3884 custom_target(exe['name'] + stp['ext'], 3885 input: trace_events_all, 3886 output: exe['name'] + stp['ext'], 3887 install: stp['install'], 3888 install_dir: get_option('datadir') / 'systemtap/tapset', 3889 command: [ 3890 tracetool, '--group=all', '--format=' + stp['fmt'], 3891 '--binary=' + stp['bin'], 3892 '--target-name=' + target_name, 3893 '--target-type=' + target_type, 3894 '--probe-prefix=qemu.' + target_type + '.' + target_name, 3895 '@INPUT@', '@OUTPUT@' 3896 ], 3897 depend_files: tracetool_depends) 3898 endforeach 3899 endif 3900 endforeach 3901endforeach 3902 3903# Other build targets 3904 3905if 'CONFIG_PLUGIN' in config_host 3906 install_headers('include/qemu/qemu-plugin.h') 3907endif 3908 3909subdir('qga') 3910 3911# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3912# when we don't build tools or system 3913if xkbcommon.found() 3914 # used for the update-keymaps target, so include rules even if !have_tools 3915 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 3916 dependencies: [qemuutil, xkbcommon], install: have_tools) 3917endif 3918 3919if have_tools 3920 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 3921 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 3922 qemu_io = executable('qemu-io', files('qemu-io.c'), 3923 dependencies: [block, qemuutil], install: true) 3924 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 3925 dependencies: [blockdev, qemuutil, gnutls, selinux], 3926 install: true) 3927 3928 subdir('storage-daemon') 3929 subdir('contrib/rdmacm-mux') 3930 subdir('contrib/elf2dmp') 3931 3932 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 3933 dependencies: qemuutil, 3934 install: true) 3935 3936 if have_vhost_user 3937 subdir('contrib/vhost-user-blk') 3938 subdir('contrib/vhost-user-gpu') 3939 subdir('contrib/vhost-user-input') 3940 subdir('contrib/vhost-user-scsi') 3941 endif 3942 3943 if targetos == 'linux' 3944 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 3945 dependencies: [qemuutil, libcap_ng], 3946 install: true, 3947 install_dir: get_option('libexecdir')) 3948 3949 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 3950 dependencies: [authz, crypto, io, qom, qemuutil, 3951 libcap_ng, mpathpersist], 3952 install: true) 3953 endif 3954 3955 if have_ivshmem 3956 subdir('contrib/ivshmem-client') 3957 subdir('contrib/ivshmem-server') 3958 endif 3959endif 3960 3961subdir('scripts') 3962subdir('tools') 3963subdir('pc-bios') 3964subdir('docs') 3965subdir('tests') 3966if gtk.found() 3967 subdir('po') 3968endif 3969 3970if host_machine.system() == 'windows' 3971 nsis_cmd = [ 3972 find_program('scripts/nsis.py'), 3973 '@OUTPUT@', 3974 get_option('prefix'), 3975 meson.current_source_dir(), 3976 glib_pc.get_variable('bindir'), 3977 host_machine.cpu(), 3978 '--', 3979 '-DDISPLAYVERSION=' + meson.project_version(), 3980 ] 3981 if build_docs 3982 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 3983 endif 3984 if gtk.found() 3985 nsis_cmd += '-DCONFIG_GTK=y' 3986 endif 3987 3988 nsis = custom_target('nsis', 3989 output: 'qemu-setup-' + meson.project_version() + '.exe', 3990 input: files('qemu.nsi'), 3991 build_always_stale: true, 3992 command: nsis_cmd + ['@INPUT@']) 3993 alias_target('installer', nsis) 3994endif 3995 3996######################### 3997# Configuration summary # 3998######################### 3999 4000# Directories 4001summary_info = {} 4002summary_info += {'Install prefix': get_option('prefix')} 4003summary_info += {'BIOS directory': qemu_datadir} 4004pathsep = targetos == 'windows' ? ';' : ':' 4005summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 4006summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 4007summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 4008summary_info += {'module directory': qemu_moddir} 4009summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 4010summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 4011summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 4012if targetos != 'windows' 4013 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 4014 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 4015else 4016 summary_info += {'local state directory': 'queried at runtime'} 4017endif 4018summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 4019summary_info += {'Build directory': meson.current_build_dir()} 4020summary_info += {'Source path': meson.current_source_dir()} 4021summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 4022summary(summary_info, bool_yn: true, section: 'Directories') 4023 4024# Host binaries 4025summary_info = {} 4026summary_info += {'git': config_host['GIT']} 4027summary_info += {'make': config_host['MAKE']} 4028summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 4029summary_info += {'sphinx-build': sphinx_build} 4030if config_host.has_key('HAVE_GDB_BIN') 4031 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 4032endif 4033summary_info += {'iasl': iasl} 4034summary_info += {'genisoimage': config_host['GENISOIMAGE']} 4035if targetos == 'windows' and have_ga 4036 summary_info += {'wixl': wixl} 4037endif 4038if slirp.found() and have_system 4039 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 4040endif 4041summary(summary_info, bool_yn: true, section: 'Host binaries') 4042 4043# Configurable features 4044summary_info = {} 4045summary_info += {'Documentation': build_docs} 4046summary_info += {'system-mode emulation': have_system} 4047summary_info += {'user-mode emulation': have_user} 4048summary_info += {'block layer': have_block} 4049summary_info += {'Install blobs': get_option('install_blobs')} 4050summary_info += {'module support': enable_modules} 4051if enable_modules 4052 summary_info += {'alternative module path': get_option('module_upgrades')} 4053endif 4054summary_info += {'fuzzing support': get_option('fuzzing')} 4055if have_system 4056 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 4057endif 4058summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 4059if 'simple' in get_option('trace_backends') 4060 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 4061endif 4062summary_info += {'D-Bus display': dbus_display} 4063summary_info += {'QOM debugging': get_option('qom_cast_debug')} 4064summary_info += {'vhost-kernel support': have_vhost_kernel} 4065summary_info += {'vhost-net support': have_vhost_net} 4066summary_info += {'vhost-user support': have_vhost_user} 4067summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 4068summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 4069summary_info += {'vhost-vdpa support': have_vhost_vdpa} 4070summary_info += {'build guest agent': have_ga} 4071summary(summary_info, bool_yn: true, section: 'Configurable features') 4072 4073# Compilation information 4074summary_info = {} 4075summary_info += {'host CPU': cpu} 4076summary_info += {'host endianness': build_machine.endian()} 4077summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 4078summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 4079if link_language == 'cpp' 4080 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 4081else 4082 summary_info += {'C++ compiler': false} 4083endif 4084if targetos == 'darwin' 4085 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 4086endif 4087option_cflags = (get_option('debug') ? ['-g'] : []) 4088if get_option('optimization') != 'plain' 4089 option_cflags += ['-O' + get_option('optimization')] 4090endif 4091summary_info += {'CFLAGS': ' '.join(get_option('c_args') + option_cflags)} 4092if link_language == 'cpp' 4093 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') + option_cflags)} 4094endif 4095if targetos == 'darwin' 4096 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') + option_cflags)} 4097endif 4098link_args = get_option(link_language + '_link_args') 4099if link_args.length() > 0 4100 summary_info += {'LDFLAGS': ' '.join(link_args)} 4101endif 4102summary_info += {'QEMU_CFLAGS': ' '.join(qemu_common_flags + qemu_cflags)} 4103if 'cpp' in all_languages 4104 summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_common_flags + qemu_cxxflags)} 4105endif 4106if 'objc' in all_languages 4107 summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_common_flags)} 4108endif 4109summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 4110summary_info += {'profiler': get_option('profiler')} 4111summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 4112summary_info += {'PIE': get_option('b_pie')} 4113summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 4114summary_info += {'malloc trim support': has_malloc_trim} 4115summary_info += {'membarrier': have_membarrier} 4116summary_info += {'debug graph lock': get_option('debug_graph_lock')} 4117summary_info += {'debug stack usage': get_option('debug_stack_usage')} 4118summary_info += {'mutex debugging': get_option('debug_mutex')} 4119summary_info += {'memory allocator': get_option('malloc')} 4120summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 4121summary_info += {'avx512bw optimization': config_host_data.get('CONFIG_AVX512BW_OPT')} 4122summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 4123if get_option('gprof') 4124 gprof_info = 'YES (deprecated)' 4125else 4126 gprof_info = get_option('gprof') 4127endif 4128summary_info += {'gprof': gprof_info} 4129summary_info += {'gcov': get_option('b_coverage')} 4130summary_info += {'thread sanitizer': get_option('tsan')} 4131summary_info += {'CFI support': get_option('cfi')} 4132if get_option('cfi') 4133 summary_info += {'CFI debug support': get_option('cfi_debug')} 4134endif 4135summary_info += {'strip binaries': get_option('strip')} 4136summary_info += {'sparse': sparse} 4137summary_info += {'mingw32 support': targetos == 'windows'} 4138summary(summary_info, bool_yn: true, section: 'Compilation') 4139 4140# snarf the cross-compilation information for tests 4141summary_info = {} 4142have_cross = false 4143foreach target: target_dirs 4144 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 4145 if fs.exists(tcg_mak) 4146 config_cross_tcg = keyval.load(tcg_mak) 4147 if 'CC' in config_cross_tcg 4148 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 4149 have_cross = true 4150 endif 4151 endif 4152endforeach 4153if have_cross 4154 summary(summary_info, bool_yn: true, section: 'Cross compilers') 4155endif 4156 4157# Targets and accelerators 4158summary_info = {} 4159if have_system 4160 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 4161 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 4162 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 4163 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 4164 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')} 4165 summary_info += {'Xen support': xen.found()} 4166 if xen.found() 4167 summary_info += {'xen ctrl version': xen.version()} 4168 endif 4169 summary_info += {'Xen emulation': config_all.has_key('CONFIG_XEN_EMU')} 4170endif 4171summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 4172if config_all.has_key('CONFIG_TCG') 4173 if get_option('tcg_interpreter') 4174 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 4175 else 4176 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 4177 endif 4178 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')} 4179 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 4180endif 4181summary_info += {'target list': ' '.join(target_dirs)} 4182if have_system 4183 summary_info += {'default devices': get_option('default_devices')} 4184 summary_info += {'out of process emulation': multiprocess_allowed} 4185 summary_info += {'vfio-user server': vfio_user_server_allowed} 4186endif 4187summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 4188 4189# Block layer 4190summary_info = {} 4191summary_info += {'coroutine backend': coroutine_backend} 4192summary_info += {'coroutine pool': have_coroutine_pool} 4193if have_block 4194 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 4195 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 4196 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 4197 summary_info += {'VirtFS (9P) support': have_virtfs} 4198 summary_info += {'VirtFS (9P) Proxy Helper support': have_virtfs_proxy_helper} 4199 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')} 4200 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 4201 summary_info += {'bochs support': get_option('bochs').allowed()} 4202 summary_info += {'cloop support': get_option('cloop').allowed()} 4203 summary_info += {'dmg support': get_option('dmg').allowed()} 4204 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 4205 summary_info += {'vdi support': get_option('vdi').allowed()} 4206 summary_info += {'vhdx support': get_option('vhdx').allowed()} 4207 summary_info += {'vmdk support': get_option('vmdk').allowed()} 4208 summary_info += {'vpc support': get_option('vpc').allowed()} 4209 summary_info += {'vvfat support': get_option('vvfat').allowed()} 4210 summary_info += {'qed support': get_option('qed').allowed()} 4211 summary_info += {'parallels support': get_option('parallels').allowed()} 4212 summary_info += {'FUSE exports': fuse} 4213 summary_info += {'VDUSE block exports': have_vduse_blk_export} 4214endif 4215summary(summary_info, bool_yn: true, section: 'Block layer support') 4216 4217# Crypto 4218summary_info = {} 4219summary_info += {'TLS priority': get_option('tls_priority')} 4220summary_info += {'GNUTLS support': gnutls} 4221if gnutls.found() 4222 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 4223endif 4224summary_info += {'libgcrypt': gcrypt} 4225summary_info += {'nettle': nettle} 4226if nettle.found() 4227 summary_info += {' XTS': xts != 'private'} 4228endif 4229summary_info += {'AF_ALG support': have_afalg} 4230summary_info += {'rng-none': get_option('rng_none')} 4231summary_info += {'Linux keyring': have_keyring} 4232summary(summary_info, bool_yn: true, section: 'Crypto') 4233 4234# Libraries 4235summary_info = {} 4236if targetos == 'darwin' 4237 summary_info += {'Cocoa support': cocoa} 4238 summary_info += {'vmnet.framework support': vmnet} 4239endif 4240summary_info += {'SDL support': sdl} 4241summary_info += {'SDL image support': sdl_image} 4242summary_info += {'GTK support': gtk} 4243summary_info += {'pixman': pixman} 4244summary_info += {'VTE support': vte} 4245summary_info += {'slirp support': slirp} 4246summary_info += {'libtasn1': tasn1} 4247summary_info += {'PAM': pam} 4248summary_info += {'iconv support': iconv} 4249summary_info += {'curses support': curses} 4250summary_info += {'virgl support': virgl} 4251summary_info += {'blkio support': blkio} 4252summary_info += {'curl support': curl} 4253summary_info += {'Multipath support': mpathpersist} 4254summary_info += {'PNG support': png} 4255summary_info += {'VNC support': vnc} 4256if vnc.found() 4257 summary_info += {'VNC SASL support': sasl} 4258 summary_info += {'VNC JPEG support': jpeg} 4259endif 4260if targetos not in ['darwin', 'haiku', 'windows'] 4261 summary_info += {'OSS support': oss} 4262 summary_info += {'sndio support': sndio} 4263elif targetos == 'darwin' 4264 summary_info += {'CoreAudio support': coreaudio} 4265elif targetos == 'windows' 4266 summary_info += {'DirectSound support': dsound} 4267endif 4268if targetos == 'linux' 4269 summary_info += {'ALSA support': alsa} 4270 summary_info += {'PulseAudio support': pulse} 4271endif 4272summary_info += {'Pipewire support': pipewire} 4273summary_info += {'JACK support': jack} 4274summary_info += {'brlapi support': brlapi} 4275summary_info += {'vde support': vde} 4276summary_info += {'netmap support': have_netmap} 4277summary_info += {'l2tpv3 support': have_l2tpv3} 4278summary_info += {'Linux AIO support': libaio} 4279summary_info += {'Linux io_uring support': linux_io_uring} 4280summary_info += {'ATTR/XATTR support': libattr} 4281summary_info += {'RDMA support': rdma} 4282summary_info += {'PVRDMA support': have_pvrdma} 4283summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 4284summary_info += {'libcap-ng support': libcap_ng} 4285summary_info += {'bpf support': libbpf} 4286summary_info += {'spice protocol support': spice_protocol} 4287if spice_protocol.found() 4288 summary_info += {' spice server support': spice} 4289endif 4290summary_info += {'rbd support': rbd} 4291summary_info += {'smartcard support': cacard} 4292summary_info += {'U2F support': u2f} 4293summary_info += {'libusb': libusb} 4294summary_info += {'usb net redir': usbredir} 4295summary_info += {'OpenGL support (epoxy)': opengl} 4296summary_info += {'GBM': gbm} 4297summary_info += {'libiscsi support': libiscsi} 4298summary_info += {'libnfs support': libnfs} 4299if targetos == 'windows' 4300 if have_ga 4301 summary_info += {'QGA VSS support': have_qga_vss} 4302 endif 4303endif 4304summary_info += {'seccomp support': seccomp} 4305summary_info += {'GlusterFS support': glusterfs} 4306summary_info += {'TPM support': have_tpm} 4307summary_info += {'libssh support': libssh} 4308summary_info += {'lzo support': lzo} 4309summary_info += {'snappy support': snappy} 4310summary_info += {'bzip2 support': libbzip2} 4311summary_info += {'lzfse support': liblzfse} 4312summary_info += {'zstd support': zstd} 4313summary_info += {'NUMA host support': numa} 4314summary_info += {'capstone': capstone} 4315summary_info += {'libpmem support': libpmem} 4316summary_info += {'libdaxctl support': libdaxctl} 4317summary_info += {'libudev': libudev} 4318# Dummy dependency, keep .found() 4319summary_info += {'FUSE lseek': fuse_lseek.found()} 4320summary_info += {'selinux': selinux} 4321summary_info += {'libdw': libdw} 4322summary(summary_info, bool_yn: true, section: 'Dependencies') 4323 4324if not supported_cpus.contains(cpu) 4325 message() 4326 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 4327 message() 4328 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 4329 message('The QEMU project intends to remove support for this host CPU in') 4330 message('a future release if nobody volunteers to maintain it and to') 4331 message('provide a build host for our continuous integration setup.') 4332 message('configure has succeeded and you can continue to build, but') 4333 message('if you care about QEMU on this platform you should contact') 4334 message('us upstream at qemu-devel@nongnu.org.') 4335endif 4336 4337if not supported_oses.contains(targetos) 4338 message() 4339 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 4340 message() 4341 message('Host OS ' + targetos + 'support is not currently maintained.') 4342 message('The QEMU project intends to remove support for this host OS in') 4343 message('a future release if nobody volunteers to maintain it and to') 4344 message('provide a build host for our continuous integration setup.') 4345 message('configure has succeeded and you can continue to build, but') 4346 message('if you care about QEMU on this platform you should contact') 4347 message('us upstream at qemu-devel@nongnu.org.') 4348endif 4349