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