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