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