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