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