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 1309# Check whether statx() provides mount ID information 1310 1311statx_mnt_id_test = gnu_source_prefix + ''' 1312 #include <sys/stat.h> 1313 int main(void) { 1314 struct statx statxbuf; 1315 statx(0, "", 0, STATX_BASIC_STATS | STATX_MNT_ID, &statxbuf); 1316 return statxbuf.stx_mnt_id; 1317 }''' 1318 1319has_statx_mnt_id = cc.links(statx_mnt_id_test) 1320 1321have_vhost_user_blk_server = get_option('vhost_user_blk_server') \ 1322 .require(targetos == 'linux', 1323 error_message: 'vhost_user_blk_server requires linux') \ 1324 .require('CONFIG_VHOST_USER' in config_host, 1325 error_message: 'vhost_user_blk_server requires vhost-user support') \ 1326 .disable_auto_if(not have_system) \ 1327 .allowed() 1328 1329if get_option('fuse').disabled() and get_option('fuse_lseek').enabled() 1330 error('Cannot enable fuse-lseek while fuse is disabled') 1331endif 1332 1333fuse = dependency('fuse3', required: get_option('fuse'), 1334 version: '>=3.1', method: 'pkg-config', 1335 kwargs: static_kwargs) 1336 1337fuse_lseek = not_found 1338if get_option('fuse_lseek').allowed() 1339 if fuse.version().version_compare('>=3.8') 1340 # Dummy dependency 1341 fuse_lseek = declare_dependency() 1342 elif get_option('fuse_lseek').enabled() 1343 if fuse.found() 1344 error('fuse-lseek requires libfuse >=3.8, found ' + fuse.version()) 1345 else 1346 error('fuse-lseek requires libfuse, which was not found') 1347 endif 1348 endif 1349endif 1350 1351# libbpf 1352libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config') 1353if libbpf.found() and not cc.links(''' 1354 #include <bpf/libbpf.h> 1355 int main(void) 1356 { 1357 bpf_object__destroy_skeleton(NULL); 1358 return 0; 1359 }''', dependencies: libbpf) 1360 libbpf = not_found 1361 if get_option('bpf').enabled() 1362 error('libbpf skeleton test failed') 1363 else 1364 warning('libbpf skeleton test failed, disabling') 1365 endif 1366endif 1367 1368################# 1369# config-host.h # 1370################# 1371 1372audio_drivers_selected = [] 1373if have_system 1374 audio_drivers_available = { 1375 'alsa': alsa.found(), 1376 'coreaudio': coreaudio.found(), 1377 'dsound': dsound.found(), 1378 'jack': jack.found(), 1379 'oss': oss.found(), 1380 'pa': pulse.found(), 1381 'sdl': sdl.found(), 1382 } 1383 foreach k, v: audio_drivers_available 1384 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v) 1385 endforeach 1386 1387 # Default to native drivers first, OSS second, SDL third 1388 audio_drivers_priority = \ 1389 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \ 1390 (targetos == 'linux' ? [] : [ 'sdl' ]) 1391 audio_drivers_default = [] 1392 foreach k: audio_drivers_priority 1393 if audio_drivers_available[k] 1394 audio_drivers_default += k 1395 endif 1396 endforeach 1397 1398 foreach k: get_option('audio_drv_list') 1399 if k == 'default' 1400 audio_drivers_selected += audio_drivers_default 1401 elif not audio_drivers_available[k] 1402 error('Audio driver "@0@" not available.'.format(k)) 1403 else 1404 audio_drivers_selected += k 1405 endif 1406 endforeach 1407endif 1408config_host_data.set('CONFIG_AUDIO_DRIVERS', 1409 '"' + '", "'.join(audio_drivers_selected) + '", ') 1410 1411if get_option('cfi') 1412 cfi_flags=[] 1413 # Check for dependency on LTO 1414 if not get_option('b_lto') 1415 error('Selected Control-Flow Integrity but LTO is disabled') 1416 endif 1417 if config_host.has_key('CONFIG_MODULES') 1418 error('Selected Control-Flow Integrity is not compatible with modules') 1419 endif 1420 # Check for cfi flags. CFI requires LTO so we can't use 1421 # get_supported_arguments, but need a more complex "compiles" which allows 1422 # custom arguments 1423 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall', 1424 args: ['-flto', '-fsanitize=cfi-icall'] ) 1425 cfi_flags += '-fsanitize=cfi-icall' 1426 else 1427 error('-fsanitize=cfi-icall is not supported by the compiler') 1428 endif 1429 if cc.compiles('int main () { return 0; }', 1430 name: '-fsanitize-cfi-icall-generalize-pointers', 1431 args: ['-flto', '-fsanitize=cfi-icall', 1432 '-fsanitize-cfi-icall-generalize-pointers'] ) 1433 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers' 1434 else 1435 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler') 1436 endif 1437 if get_option('cfi_debug') 1438 if cc.compiles('int main () { return 0; }', 1439 name: '-fno-sanitize-trap=cfi-icall', 1440 args: ['-flto', '-fsanitize=cfi-icall', 1441 '-fno-sanitize-trap=cfi-icall'] ) 1442 cfi_flags += '-fno-sanitize-trap=cfi-icall' 1443 else 1444 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler') 1445 endif 1446 endif 1447 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) 1448 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) 1449endif 1450 1451have_host_block_device = (targetos != 'darwin' or 1452 cc.has_header('IOKit/storage/IOMedia.h')) 1453 1454# FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333 1455dbus_display = get_option('dbus_display') \ 1456 .require(gio.version().version_compare('>=2.64'), 1457 error_message: '-display dbus requires glib>=2.64') \ 1458 .require(enable_modules, 1459 error_message: '-display dbus requires --enable-modules') \ 1460 .require(config_host.has_key('GDBUS_CODEGEN'), 1461 error_message: '-display dbus requires gdbus-codegen') \ 1462 .allowed() 1463 1464have_virtfs = get_option('virtfs') \ 1465 .require(targetos == 'linux' or targetos == 'darwin', 1466 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \ 1467 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'), 1468 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \ 1469 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()), 1470 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \ 1471 .disable_auto_if(not have_tools and not have_system) \ 1472 .allowed() 1473 1474have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools 1475 1476foreach k : get_option('trace_backends') 1477 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true) 1478endforeach 1479config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file')) 1480if get_option('iasl') != '' 1481 config_host_data.set_quoted('CONFIG_IASL', get_option('iasl')) 1482endif 1483config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) 1484config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) 1485config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) 1486config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir) 1487config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir) 1488config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('qemu_firmwarepath')) 1489config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir')) 1490config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir) 1491config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir')) 1492config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir')) 1493config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) 1494config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) 1495 1496have_slirp_smbd = get_option('slirp_smbd') \ 1497 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \ 1498 .allowed() 1499if have_slirp_smbd 1500 smbd_path = get_option('smbd') 1501 if smbd_path == '' 1502 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd') 1503 endif 1504 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path) 1505endif 1506 1507config_host_data.set('HOST_' + host_arch.to_upper(), 1) 1508 1509config_host_data.set('CONFIG_ATTR', libattr.found()) 1510config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools')) 1511config_host_data.set('CONFIG_BRLAPI', brlapi.found()) 1512config_host_data.set('CONFIG_COCOA', cocoa.found()) 1513config_host_data.set('CONFIG_FUZZ', get_option('fuzzing')) 1514config_host_data.set('CONFIG_GCOV', get_option('b_coverage')) 1515config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 1516config_host_data.set('CONFIG_LZO', lzo.found()) 1517config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 1518config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api) 1519config_host_data.set('CONFIG_CURL', curl.found()) 1520config_host_data.set('CONFIG_CURSES', curses.found()) 1521config_host_data.set('CONFIG_GBM', gbm.found()) 1522config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 1523if glusterfs.found() 1524 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4')) 1525 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5')) 1526 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6')) 1527 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6')) 1528 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat) 1529 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat) 1530endif 1531config_host_data.set('CONFIG_GTK', gtk.found()) 1532config_host_data.set('CONFIG_VTE', vte.found()) 1533config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 1534config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 1535config_host_data.set('CONFIG_EBPF', libbpf.found()) 1536config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 1537config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 1538config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 1539config_host_data.set('CONFIG_LIBSSH', libssh.found()) 1540config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 1541config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 1542config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 1543config_host_data.set('CONFIG_NUMA', numa.found()) 1544config_host_data.set('CONFIG_PROFILER', get_option('profiler')) 1545config_host_data.set('CONFIG_RBD', rbd.found()) 1546config_host_data.set('CONFIG_SDL', sdl.found()) 1547config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 1548config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 1549config_host_data.set('CONFIG_SNAPPY', snappy.found()) 1550config_host_data.set('CONFIG_TPM', have_tpm) 1551config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 1552config_host_data.set('CONFIG_VDE', vde.found()) 1553config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 1554config_host_data.set('CONFIG_VNC', vnc.found()) 1555config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 1556config_host_data.set('CONFIG_VNC_PNG', png.found()) 1557config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 1558config_host_data.set('CONFIG_VIRTFS', have_virtfs) 1559config_host_data.set('CONFIG_VTE', vte.found()) 1560config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 1561config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 1562config_host_data.set('CONFIG_GETTID', has_gettid) 1563config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 1564config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 1565config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 1566config_host_data.set('CONFIG_NETTLE', nettle.found()) 1567config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 1568config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 1569config_host_data.set('CONFIG_STATX', has_statx) 1570config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 1571config_host_data.set('CONFIG_ZSTD', zstd.found()) 1572config_host_data.set('CONFIG_FUSE', fuse.found()) 1573config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 1574config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 1575if spice_protocol.found() 1576config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 1577config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 1578config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 1579endif 1580config_host_data.set('CONFIG_SPICE', spice.found()) 1581config_host_data.set('CONFIG_X11', x11.found()) 1582config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 1583config_host_data.set('CONFIG_CFI', get_option('cfi')) 1584config_host_data.set('CONFIG_SELINUX', selinux.found()) 1585config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 1586config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 1587config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 1588config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 1589 1590config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 1591config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 1592config_host_data.set('HOST_WORDS_BIGENDIAN', host_machine.endian() == 'big') 1593 1594have_coroutine_pool = get_option('coroutine_pool') 1595if get_option('debug_stack_usage') and have_coroutine_pool 1596 message('Disabling coroutine pool to measure stack usage') 1597 have_coroutine_pool = false 1598endif 1599config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool) 1600config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 1601config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 1602config_host_data.set('CONFIG_GPROF', get_option('gprof')) 1603config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed()) 1604config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 1605config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed()) 1606 1607# has_header 1608config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 1609config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 1610config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 1611config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 1612config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 1613config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 1614config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 1615config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 1616config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 1617 1618# has_function 1619config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 1620config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 1621config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 1622config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 1623config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 1624# Note that we need to specify prefix: here to avoid incorrectly 1625# thinking that Windows has posix_memalign() 1626config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 1627config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 1628config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 1629config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 1630config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 1631config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 1632config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 1633config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads)) 1634config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 1635config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 1636config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 1637config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 1638config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 1639config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 1640config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 1641config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 1642config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 1643if rdma.found() 1644 config_host_data.set('HAVE_IBV_ADVISE_MR', 1645 cc.has_function('ibv_advise_mr', 1646 args: config_host['RDMA_LIBS'].split(), 1647 prefix: '#include <infiniband/verbs.h>')) 1648endif 1649 1650# has_header_symbol 1651config_host_data.set('CONFIG_BYTESWAP_H', 1652 cc.has_header_symbol('byteswap.h', 'bswap_32')) 1653config_host_data.set('CONFIG_EPOLL_CREATE1', 1654 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 1655config_host_data.set('CONFIG_HAS_ENVIRON', 1656 cc.has_header_symbol('unistd.h', 'environ', prefix: gnu_source_prefix)) 1657config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 1658 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 1659 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 1660config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 1661 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 1662config_host_data.set('CONFIG_FIEMAP', 1663 cc.has_header('linux/fiemap.h') and 1664 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 1665config_host_data.set('CONFIG_GETRANDOM', 1666 cc.has_function('getrandom') and 1667 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 1668config_host_data.set('CONFIG_INOTIFY', 1669 cc.has_header_symbol('sys/inotify.h', 'inotify_init')) 1670config_host_data.set('CONFIG_INOTIFY1', 1671 cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) 1672config_host_data.set('CONFIG_MACHINE_BSWAP_H', 1673 cc.has_header_symbol('machine/bswap.h', 'bswap32', 1674 prefix: '''#include <sys/endian.h> 1675 #include <sys/types.h>''')) 1676config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 1677 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 1678config_host_data.set('CONFIG_RTNETLINK', 1679 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 1680config_host_data.set('CONFIG_SYSMACROS', 1681 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 1682config_host_data.set('HAVE_OPTRESET', 1683 cc.has_header_symbol('getopt.h', 'optreset')) 1684config_host_data.set('HAVE_IPPROTO_MPTCP', 1685 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 1686 1687# has_member 1688config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 1689 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 1690 prefix: '#include <signal.h>')) 1691config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 1692 cc.has_member('struct stat', 'st_atim', 1693 prefix: '#include <sys/stat.h>')) 1694 1695# has_type 1696config_host_data.set('CONFIG_IOVEC', 1697 cc.has_type('struct iovec', 1698 prefix: '#include <sys/uio.h>')) 1699config_host_data.set('HAVE_UTMPX', 1700 cc.has_type('struct utmpx', 1701 prefix: '#include <utmpx.h>')) 1702 1703config_host_data.set('CONFIG_EVENTFD', cc.links(''' 1704 #include <sys/eventfd.h> 1705 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 1706config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 1707 #include <unistd.h> 1708 int main(void) { 1709 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 1710 return fdatasync(0); 1711 #else 1712 #error Not supported 1713 #endif 1714 }''')) 1715config_host_data.set('CONFIG_MADVISE', cc.links(gnu_source_prefix + ''' 1716 #include <sys/types.h> 1717 #include <sys/mman.h> 1718 #include <stddef.h> 1719 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''')) 1720config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 1721 #include <sys/mman.h> 1722 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 1723config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 1724 #include <fcntl.h> 1725 #if !defined(AT_EMPTY_PATH) 1726 # error missing definition 1727 #else 1728 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 1729 #endif''')) 1730config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + ''' 1731 #include <unistd.h> 1732 #include <fcntl.h> 1733 1734 int main(void) 1735 { 1736 int pipefd[2]; 1737 return pipe2(pipefd, O_CLOEXEC); 1738 }''')) 1739config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 1740 #include <sys/mman.h> 1741 #include <stddef.h> 1742 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 1743 1744config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 1745 #include <pthread.h> 1746 1747 static void *f(void *p) { return NULL; } 1748 int main(void) 1749 { 1750 pthread_t thread; 1751 pthread_create(&thread, 0, f, 0); 1752 pthread_setname_np(thread, "QEMU"); 1753 return 0; 1754 }''', dependencies: threads)) 1755config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 1756 #include <pthread.h> 1757 1758 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 1759 int main(void) 1760 { 1761 pthread_t thread; 1762 pthread_create(&thread, 0, f, 0); 1763 return 0; 1764 }''', dependencies: threads)) 1765 1766config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 1767 #include <sys/signalfd.h> 1768 #include <stddef.h> 1769 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 1770config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 1771 #include <unistd.h> 1772 #include <fcntl.h> 1773 #include <limits.h> 1774 1775 int main(void) 1776 { 1777 int len, fd = 0; 1778 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 1779 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 1780 return 0; 1781 }''')) 1782 1783config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 1784 #include <sys/mman.h> 1785 int main(int argc, char *argv[]) { 1786 return mlockall(MCL_FUTURE); 1787 }''')) 1788 1789have_l2tpv3 = false 1790if get_option('l2tpv3').allowed() and have_system 1791 have_l2tpv3 = cc.has_type('struct mmsghdr', 1792 prefix: gnu_source_prefix + ''' 1793 #include <sys/socket.h> 1794 #include <linux/ip.h>''') 1795endif 1796config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 1797 1798have_netmap = false 1799if get_option('netmap').allowed() and have_system 1800 have_netmap = cc.compiles(''' 1801 #include <inttypes.h> 1802 #include <net/if.h> 1803 #include <net/netmap.h> 1804 #include <net/netmap_user.h> 1805 #if (NETMAP_API < 11) || (NETMAP_API > 15) 1806 #error 1807 #endif 1808 int main(void) { return 0; }''') 1809 if not have_netmap and get_option('netmap').enabled() 1810 error('Netmap headers not available') 1811 endif 1812endif 1813config_host_data.set('CONFIG_NETMAP', have_netmap) 1814 1815# Work around a system header bug with some kernel/XFS header 1816# versions where they both try to define 'struct fsxattr': 1817# xfs headers will not try to redefine structs from linux headers 1818# if this macro is set. 1819config_host_data.set('HAVE_FSXATTR', cc.links(''' 1820 #include <linux/fs.h> 1821 struct fsxattr foo; 1822 int main(void) { 1823 return 0; 1824 }''')) 1825 1826# Some versions of Mac OS X incorrectly define SIZE_MAX 1827config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 1828 #include <stdint.h> 1829 #include <stdio.h> 1830 int main(int argc, char *argv[]) { 1831 return printf("%zu", SIZE_MAX); 1832 }''', args: ['-Werror'])) 1833 1834# See if 64-bit atomic operations are supported. 1835# Note that without __atomic builtins, we can only 1836# assume atomic loads/stores max at pointer size. 1837config_host_data.set('CONFIG_ATOMIC64', cc.links(''' 1838 #include <stdint.h> 1839 int main(void) 1840 { 1841 uint64_t x = 0, y = 0; 1842 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 1843 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 1844 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 1845 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 1846 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 1847 return 0; 1848 }''')) 1849 1850config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 1851 #include <sys/auxv.h> 1852 int main(void) { 1853 return getauxval(AT_HWCAP) == 0; 1854 }''')) 1855 1856have_cpuid_h = cc.links(''' 1857 #include <cpuid.h> 1858 int main(void) { 1859 unsigned a, b, c, d; 1860 unsigned max = __get_cpuid_max(0, 0); 1861 1862 if (max >= 1) { 1863 __cpuid(1, a, b, c, d); 1864 } 1865 1866 if (max >= 7) { 1867 __cpuid_count(7, 0, a, b, c, d); 1868 } 1869 1870 return 0; 1871 }''') 1872config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 1873 1874config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 1875 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 1876 .require(cc.links(''' 1877 #pragma GCC push_options 1878 #pragma GCC target("avx2") 1879 #include <cpuid.h> 1880 #include <immintrin.h> 1881 static int bar(void *a) { 1882 __m256i x = *(__m256i *)a; 1883 return _mm256_testz_si256(x, x); 1884 } 1885 int main(int argc, char *argv[]) { return bar(argv[0]); } 1886 '''), error_message: 'AVX2 not available').allowed()) 1887 1888config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ 1889 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \ 1890 .require(cc.links(''' 1891 #pragma GCC push_options 1892 #pragma GCC target("avx512f") 1893 #include <cpuid.h> 1894 #include <immintrin.h> 1895 static int bar(void *a) { 1896 __m512i x = *(__m512i *)a; 1897 return _mm512_test_epi64_mask(x, x); 1898 } 1899 int main(int argc, char *argv[]) { return bar(argv[0]); } 1900 '''), error_message: 'AVX512F not available').allowed()) 1901 1902if get_option('membarrier').disabled() 1903 have_membarrier = false 1904elif targetos == 'windows' 1905 have_membarrier = true 1906elif targetos == 'linux' 1907 have_membarrier = cc.compiles(''' 1908 #include <linux/membarrier.h> 1909 #include <sys/syscall.h> 1910 #include <unistd.h> 1911 #include <stdlib.h> 1912 int main(void) { 1913 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 1914 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 1915 exit(0); 1916 }''') 1917endif 1918config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 1919 .require(have_membarrier, error_message: 'membarrier system call not available') \ 1920 .allowed()) 1921 1922have_afalg = get_option('crypto_afalg') \ 1923 .require(cc.compiles(gnu_source_prefix + ''' 1924 #include <errno.h> 1925 #include <sys/types.h> 1926 #include <sys/socket.h> 1927 #include <linux/if_alg.h> 1928 int main(void) { 1929 int sock; 1930 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 1931 return sock; 1932 } 1933 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 1934config_host_data.set('CONFIG_AF_ALG', have_afalg) 1935 1936config_host_data.set('CONFIG_AF_VSOCK', cc.compiles(gnu_source_prefix + ''' 1937 #include <errno.h> 1938 #include <sys/types.h> 1939 #include <sys/socket.h> 1940 #if !defined(AF_VSOCK) 1941 # error missing AF_VSOCK flag 1942 #endif 1943 #include <linux/vm_sockets.h> 1944 int main(void) { 1945 int sock, ret; 1946 struct sockaddr_vm svm; 1947 socklen_t len = sizeof(svm); 1948 sock = socket(AF_VSOCK, SOCK_STREAM, 0); 1949 ret = getpeername(sock, (struct sockaddr *)&svm, &len); 1950 if ((ret == -1) && (errno == ENOTCONN)) { 1951 return 0; 1952 } 1953 return -1; 1954 }''')) 1955 1956have_vss = false 1957if targetos == 'windows' and link_language == 'cpp' 1958 have_vss = cxx.compiles(''' 1959 #define __MIDL_user_allocate_free_DEFINED__ 1960 #include <inc/win2003/vss.h> 1961 int main(void) { return VSS_CTX_BACKUP; }''') 1962endif 1963 1964have_ntddscsi = false 1965if targetos == 'windows' 1966 have_ntddscsi = cc.compiles(''' 1967 #include <windows.h> 1968 #include <ntddscsi.h> 1969 int main(void) { 1970 #if !defined(IOCTL_SCSI_GET_ADDRESS) 1971 #error Missing required ioctl definitions 1972 #endif 1973 SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 }; 1974 return addr.Lun; 1975 } 1976''') 1977endif 1978config_host_data.set('HAVE_NTDDSCSI', have_ntddscsi) 1979 1980ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target 1981 'HAVE_GDB_BIN'] 1982arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST'] 1983foreach k, v: config_host 1984 if ignored.contains(k) 1985 # do nothing 1986 elif arrays.contains(k) 1987 if v != '' 1988 v = '"' + '", "'.join(v.split()) + '", ' 1989 endif 1990 config_host_data.set(k, v) 1991 elif k.startswith('CONFIG_') 1992 config_host_data.set(k, v == 'y' ? 1 : v) 1993 endif 1994endforeach 1995 1996######################## 1997# Target configuration # 1998######################## 1999 2000minikconf = find_program('scripts/minikconf.py') 2001config_all = {} 2002config_all_devices = {} 2003config_all_disas = {} 2004config_devices_mak_list = [] 2005config_devices_h = {} 2006config_target_h = {} 2007config_target_mak = {} 2008 2009disassemblers = { 2010 'alpha' : ['CONFIG_ALPHA_DIS'], 2011 'arm' : ['CONFIG_ARM_DIS'], 2012 'avr' : ['CONFIG_AVR_DIS'], 2013 'cris' : ['CONFIG_CRIS_DIS'], 2014 'hexagon' : ['CONFIG_HEXAGON_DIS'], 2015 'hppa' : ['CONFIG_HPPA_DIS'], 2016 'i386' : ['CONFIG_I386_DIS'], 2017 'x86_64' : ['CONFIG_I386_DIS'], 2018 'm68k' : ['CONFIG_M68K_DIS'], 2019 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 2020 'mips' : ['CONFIG_MIPS_DIS'], 2021 'nios2' : ['CONFIG_NIOS2_DIS'], 2022 'or1k' : ['CONFIG_OPENRISC_DIS'], 2023 'ppc' : ['CONFIG_PPC_DIS'], 2024 'riscv' : ['CONFIG_RISCV_DIS'], 2025 'rx' : ['CONFIG_RX_DIS'], 2026 's390' : ['CONFIG_S390_DIS'], 2027 'sh4' : ['CONFIG_SH4_DIS'], 2028 'sparc' : ['CONFIG_SPARC_DIS'], 2029 'xtensa' : ['CONFIG_XTENSA_DIS'], 2030} 2031if link_language == 'cpp' 2032 disassemblers += { 2033 'aarch64' : [ 'CONFIG_ARM_A64_DIS'], 2034 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'], 2035 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'], 2036 } 2037endif 2038 2039have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 2040host_kconfig = \ 2041 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 2042 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 2043 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 2044 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 2045 ('CONFIG_OPENGL' in config_host ? ['CONFIG_OPENGL=y'] : []) + \ 2046 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 2047 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \ 2048 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 2049 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 2050 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 2051 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ 2052 ('CONFIG_PVRDMA' in config_host ? ['CONFIG_PVRDMA=y'] : []) + \ 2053 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) 2054 2055ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 2056 2057default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 2058actual_target_dirs = [] 2059fdt_required = [] 2060foreach target : target_dirs 2061 config_target = { 'TARGET_NAME': target.split('-')[0] } 2062 if target.endswith('linux-user') 2063 if targetos != 'linux' 2064 if default_targets 2065 continue 2066 endif 2067 error('Target @0@ is only available on a Linux host'.format(target)) 2068 endif 2069 config_target += { 'CONFIG_LINUX_USER': 'y' } 2070 elif target.endswith('bsd-user') 2071 if 'CONFIG_BSD' not in config_host 2072 if default_targets 2073 continue 2074 endif 2075 error('Target @0@ is only available on a BSD host'.format(target)) 2076 endif 2077 config_target += { 'CONFIG_BSD_USER': 'y' } 2078 elif target.endswith('softmmu') 2079 config_target += { 'CONFIG_SOFTMMU': 'y' } 2080 endif 2081 if target.endswith('-user') 2082 config_target += { 2083 'CONFIG_USER_ONLY': 'y', 2084 'CONFIG_QEMU_INTERP_PREFIX': 2085 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME']) 2086 } 2087 endif 2088 2089 accel_kconfig = [] 2090 foreach sym: accelerators 2091 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 2092 config_target += { sym: 'y' } 2093 config_all += { sym: 'y' } 2094 if sym == 'CONFIG_TCG' and tcg_arch == 'tci' 2095 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' } 2096 elif sym == 'CONFIG_XEN' and have_xen_pci_passthrough 2097 config_target += { 'CONFIG_XEN_PCI_PASSTHROUGH': 'y' } 2098 endif 2099 if target in modular_tcg 2100 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 2101 else 2102 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 2103 endif 2104 accel_kconfig += [ sym + '=y' ] 2105 endif 2106 endforeach 2107 if accel_kconfig.length() == 0 2108 if default_targets 2109 continue 2110 endif 2111 error('No accelerator available for target @0@'.format(target)) 2112 endif 2113 2114 actual_target_dirs += target 2115 config_target += keyval.load('configs/targets' / target + '.mak') 2116 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 2117 2118 if 'TARGET_NEED_FDT' in config_target 2119 fdt_required += target 2120 endif 2121 2122 # Add default keys 2123 if 'TARGET_BASE_ARCH' not in config_target 2124 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 2125 endif 2126 if 'TARGET_ABI_DIR' not in config_target 2127 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 2128 endif 2129 2130 foreach k, v: disassemblers 2131 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 2132 foreach sym: v 2133 config_target += { sym: 'y' } 2134 config_all_disas += { sym: 'y' } 2135 endforeach 2136 endif 2137 endforeach 2138 2139 config_target_data = configuration_data() 2140 foreach k, v: config_target 2141 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 2142 # do nothing 2143 elif ignored.contains(k) 2144 # do nothing 2145 elif k == 'TARGET_BASE_ARCH' 2146 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 2147 # not used to select files from sourcesets. 2148 config_target_data.set('TARGET_' + v.to_upper(), 1) 2149 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 2150 config_target_data.set_quoted(k, v) 2151 elif v == 'y' 2152 config_target_data.set(k, 1) 2153 else 2154 config_target_data.set(k, v) 2155 endif 2156 endforeach 2157 config_target_data.set('QEMU_ARCH', 2158 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 2159 config_target_h += {target: configure_file(output: target + '-config-target.h', 2160 configuration: config_target_data)} 2161 2162 if target.endswith('-softmmu') 2163 config_input = meson.get_external_property(target, 'default') 2164 config_devices_mak = target + '-config-devices.mak' 2165 config_devices_mak = configure_file( 2166 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 2167 output: config_devices_mak, 2168 depfile: config_devices_mak + '.d', 2169 capture: true, 2170 command: [minikconf, 2171 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 2172 config_devices_mak, '@DEPFILE@', '@INPUT@', 2173 host_kconfig, accel_kconfig, 2174 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y']) 2175 2176 config_devices_data = configuration_data() 2177 config_devices = keyval.load(config_devices_mak) 2178 foreach k, v: config_devices 2179 config_devices_data.set(k, 1) 2180 endforeach 2181 config_devices_mak_list += config_devices_mak 2182 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 2183 configuration: config_devices_data)} 2184 config_target += config_devices 2185 config_all_devices += config_devices 2186 endif 2187 config_target_mak += {target: config_target} 2188endforeach 2189target_dirs = actual_target_dirs 2190 2191# This configuration is used to build files that are shared by 2192# multiple binaries, and then extracted out of the "common" 2193# static_library target. 2194# 2195# We do not use all_sources()/all_dependencies(), because it would 2196# build literally all source files, including devices only used by 2197# targets that are not built for this compilation. The CONFIG_ALL 2198# pseudo symbol replaces it. 2199 2200config_all += config_all_devices 2201config_all += config_host 2202config_all += config_all_disas 2203config_all += { 2204 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'), 2205 'CONFIG_SOFTMMU': have_system, 2206 'CONFIG_USER_ONLY': have_user, 2207 'CONFIG_ALL': true, 2208} 2209 2210target_configs_h = [] 2211foreach target: target_dirs 2212 target_configs_h += config_target_h[target] 2213 target_configs_h += config_devices_h.get(target, []) 2214endforeach 2215genh += custom_target('config-poison.h', 2216 input: [target_configs_h], 2217 output: 'config-poison.h', 2218 capture: true, 2219 command: [find_program('scripts/make-config-poison.sh'), 2220 target_configs_h]) 2221 2222############## 2223# Submodules # 2224############## 2225 2226capstone = not_found 2227capstone_opt = get_option('capstone') 2228if capstone_opt in ['enabled', 'auto', 'system'] 2229 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile') 2230 capstone = dependency('capstone', version: '>=4.0', 2231 kwargs: static_kwargs, method: 'pkg-config', 2232 required: capstone_opt == 'system' or 2233 capstone_opt == 'enabled' and not have_internal) 2234 2235 # Some versions of capstone have broken pkg-config file 2236 # that reports a wrong -I path, causing the #include to 2237 # fail later. If the system has such a broken version 2238 # do not use it. 2239 if capstone.found() and not cc.compiles('#include <capstone.h>', 2240 dependencies: [capstone]) 2241 capstone = not_found 2242 if capstone_opt == 'system' 2243 error('system capstone requested, it does not appear to work') 2244 endif 2245 endif 2246 2247 if capstone.found() 2248 capstone_opt = 'system' 2249 elif have_internal 2250 capstone_opt = 'internal' 2251 else 2252 capstone_opt = 'disabled' 2253 endif 2254endif 2255if capstone_opt == 'internal' 2256 capstone_data = configuration_data() 2257 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1') 2258 2259 capstone_files = files( 2260 'capstone/cs.c', 2261 'capstone/MCInst.c', 2262 'capstone/MCInstrDesc.c', 2263 'capstone/MCRegisterInfo.c', 2264 'capstone/SStream.c', 2265 'capstone/utils.c' 2266 ) 2267 2268 if 'CONFIG_ARM_DIS' in config_all_disas 2269 capstone_data.set('CAPSTONE_HAS_ARM', '1') 2270 capstone_files += files( 2271 'capstone/arch/ARM/ARMDisassembler.c', 2272 'capstone/arch/ARM/ARMInstPrinter.c', 2273 'capstone/arch/ARM/ARMMapping.c', 2274 'capstone/arch/ARM/ARMModule.c' 2275 ) 2276 endif 2277 2278 # FIXME: This config entry currently depends on a c++ compiler. 2279 # Which is needed for building libvixl, but not for capstone. 2280 if 'CONFIG_ARM_A64_DIS' in config_all_disas 2281 capstone_data.set('CAPSTONE_HAS_ARM64', '1') 2282 capstone_files += files( 2283 'capstone/arch/AArch64/AArch64BaseInfo.c', 2284 'capstone/arch/AArch64/AArch64Disassembler.c', 2285 'capstone/arch/AArch64/AArch64InstPrinter.c', 2286 'capstone/arch/AArch64/AArch64Mapping.c', 2287 'capstone/arch/AArch64/AArch64Module.c' 2288 ) 2289 endif 2290 2291 if 'CONFIG_PPC_DIS' in config_all_disas 2292 capstone_data.set('CAPSTONE_HAS_POWERPC', '1') 2293 capstone_files += files( 2294 'capstone/arch/PowerPC/PPCDisassembler.c', 2295 'capstone/arch/PowerPC/PPCInstPrinter.c', 2296 'capstone/arch/PowerPC/PPCMapping.c', 2297 'capstone/arch/PowerPC/PPCModule.c' 2298 ) 2299 endif 2300 2301 if 'CONFIG_S390_DIS' in config_all_disas 2302 capstone_data.set('CAPSTONE_HAS_SYSZ', '1') 2303 capstone_files += files( 2304 'capstone/arch/SystemZ/SystemZDisassembler.c', 2305 'capstone/arch/SystemZ/SystemZInstPrinter.c', 2306 'capstone/arch/SystemZ/SystemZMapping.c', 2307 'capstone/arch/SystemZ/SystemZModule.c', 2308 'capstone/arch/SystemZ/SystemZMCTargetDesc.c' 2309 ) 2310 endif 2311 2312 if 'CONFIG_I386_DIS' in config_all_disas 2313 capstone_data.set('CAPSTONE_HAS_X86', 1) 2314 capstone_files += files( 2315 'capstone/arch/X86/X86Disassembler.c', 2316 'capstone/arch/X86/X86DisassemblerDecoder.c', 2317 'capstone/arch/X86/X86ATTInstPrinter.c', 2318 'capstone/arch/X86/X86IntelInstPrinter.c', 2319 'capstone/arch/X86/X86InstPrinterCommon.c', 2320 'capstone/arch/X86/X86Mapping.c', 2321 'capstone/arch/X86/X86Module.c' 2322 ) 2323 endif 2324 2325 configure_file(output: 'capstone-defs.h', configuration: capstone_data) 2326 2327 capstone_cargs = [ 2328 # FIXME: There does not seem to be a way to completely replace the c_args 2329 # that come from add_project_arguments() -- we can only add to them. 2330 # So: disable all warnings with a big hammer. 2331 '-Wno-error', '-w', 2332 2333 # Include all configuration defines via a header file, which will wind up 2334 # as a dependency on the object file, and thus changes here will result 2335 # in a rebuild. 2336 '-include', 'capstone-defs.h' 2337 ] 2338 2339 libcapstone = static_library('capstone', 2340 build_by_default: false, 2341 sources: capstone_files, 2342 c_args: capstone_cargs, 2343 include_directories: 'capstone/include') 2344 capstone = declare_dependency(link_with: libcapstone, 2345 include_directories: 'capstone/include/capstone') 2346endif 2347 2348slirp = not_found 2349slirp_opt = 'disabled' 2350if have_system 2351 slirp_opt = get_option('slirp') 2352 if slirp_opt in ['enabled', 'auto', 'system'] 2353 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') 2354 slirp = dependency('slirp', kwargs: static_kwargs, 2355 method: 'pkg-config', 2356 required: slirp_opt == 'system' or 2357 slirp_opt == 'enabled' and not have_internal) 2358 if slirp.found() 2359 slirp_opt = 'system' 2360 elif have_internal 2361 slirp_opt = 'internal' 2362 else 2363 slirp_opt = 'disabled' 2364 endif 2365 endif 2366 if slirp_opt == 'internal' 2367 slirp_deps = [] 2368 if targetos == 'windows' 2369 slirp_deps = cc.find_library('iphlpapi') 2370 elif targetos == 'darwin' 2371 slirp_deps = cc.find_library('resolv') 2372 endif 2373 slirp_conf = configuration_data() 2374 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) 2375 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1]) 2376 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2]) 2377 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version()) 2378 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"'] 2379 slirp_files = [ 2380 'slirp/src/arp_table.c', 2381 'slirp/src/bootp.c', 2382 'slirp/src/cksum.c', 2383 'slirp/src/dhcpv6.c', 2384 'slirp/src/dnssearch.c', 2385 'slirp/src/if.c', 2386 'slirp/src/ip6_icmp.c', 2387 'slirp/src/ip6_input.c', 2388 'slirp/src/ip6_output.c', 2389 'slirp/src/ip_icmp.c', 2390 'slirp/src/ip_input.c', 2391 'slirp/src/ip_output.c', 2392 'slirp/src/mbuf.c', 2393 'slirp/src/misc.c', 2394 'slirp/src/ncsi.c', 2395 'slirp/src/ndp_table.c', 2396 'slirp/src/sbuf.c', 2397 'slirp/src/slirp.c', 2398 'slirp/src/socket.c', 2399 'slirp/src/state.c', 2400 'slirp/src/stream.c', 2401 'slirp/src/tcp_input.c', 2402 'slirp/src/tcp_output.c', 2403 'slirp/src/tcp_subr.c', 2404 'slirp/src/tcp_timer.c', 2405 'slirp/src/tftp.c', 2406 'slirp/src/udp.c', 2407 'slirp/src/udp6.c', 2408 'slirp/src/util.c', 2409 'slirp/src/version.c', 2410 'slirp/src/vmstate.c', 2411 ] 2412 2413 configure_file( 2414 input : 'slirp/src/libslirp-version.h.in', 2415 output : 'libslirp-version.h', 2416 configuration: slirp_conf) 2417 2418 slirp_inc = include_directories('slirp', 'slirp/src') 2419 libslirp = static_library('slirp', 2420 build_by_default: false, 2421 sources: slirp_files, 2422 c_args: slirp_cargs, 2423 include_directories: slirp_inc) 2424 slirp = declare_dependency(link_with: libslirp, 2425 dependencies: slirp_deps, 2426 include_directories: slirp_inc) 2427 endif 2428endif 2429 2430# For CFI, we need to compile slirp as a static library together with qemu. 2431# This is because we register slirp functions as callbacks for QEMU Timers. 2432# When using a system-wide shared libslirp, the type information for the 2433# callback is missing and the timer call produces a false positive with CFI. 2434# 2435# Now that slirp_opt has been defined, check if the selected slirp is compatible 2436# with control-flow integrity. 2437if get_option('cfi') and slirp_opt == 'system' 2438 error('Control-Flow Integrity is not compatible with system-wide slirp.' \ 2439 + ' Please configure with --enable-slirp=git') 2440endif 2441 2442fdt = not_found 2443if have_system 2444 fdt_opt = get_option('fdt') 2445 if fdt_opt in ['enabled', 'auto', 'system'] 2446 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') 2447 fdt = cc.find_library('fdt', kwargs: static_kwargs, 2448 required: fdt_opt == 'system' or 2449 fdt_opt == 'enabled' and not have_internal) 2450 if fdt.found() and cc.links(''' 2451 #include <libfdt.h> 2452 #include <libfdt_env.h> 2453 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''', 2454 dependencies: fdt) 2455 fdt_opt = 'system' 2456 elif fdt_opt == 'system' 2457 error('system libfdt requested, but it is too old (1.5.1 or newer required)') 2458 elif have_internal 2459 fdt_opt = 'internal' 2460 else 2461 fdt_opt = 'disabled' 2462 fdt = not_found 2463 endif 2464 endif 2465 if fdt_opt == 'internal' 2466 fdt_files = files( 2467 'dtc/libfdt/fdt.c', 2468 'dtc/libfdt/fdt_ro.c', 2469 'dtc/libfdt/fdt_wip.c', 2470 'dtc/libfdt/fdt_sw.c', 2471 'dtc/libfdt/fdt_rw.c', 2472 'dtc/libfdt/fdt_strerror.c', 2473 'dtc/libfdt/fdt_empty_tree.c', 2474 'dtc/libfdt/fdt_addresses.c', 2475 'dtc/libfdt/fdt_overlay.c', 2476 'dtc/libfdt/fdt_check.c', 2477 ) 2478 2479 fdt_inc = include_directories('dtc/libfdt') 2480 libfdt = static_library('fdt', 2481 build_by_default: false, 2482 sources: fdt_files, 2483 include_directories: fdt_inc) 2484 fdt = declare_dependency(link_with: libfdt, 2485 include_directories: fdt_inc) 2486 endif 2487else 2488 fdt_opt = 'disabled' 2489endif 2490if not fdt.found() and fdt_required.length() > 0 2491 error('fdt not available but required by targets ' + ', '.join(fdt_required)) 2492endif 2493 2494config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2495config_host_data.set('CONFIG_FDT', fdt.found()) 2496config_host_data.set('CONFIG_SLIRP', slirp.found()) 2497 2498##################### 2499# Generated sources # 2500##################### 2501 2502genh += configure_file(output: 'config-host.h', configuration: config_host_data) 2503 2504hxtool = find_program('scripts/hxtool') 2505shaderinclude = find_program('scripts/shaderinclude.pl') 2506qapi_gen = find_program('scripts/qapi-gen.py') 2507qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 2508 meson.current_source_dir() / 'scripts/qapi/commands.py', 2509 meson.current_source_dir() / 'scripts/qapi/common.py', 2510 meson.current_source_dir() / 'scripts/qapi/error.py', 2511 meson.current_source_dir() / 'scripts/qapi/events.py', 2512 meson.current_source_dir() / 'scripts/qapi/expr.py', 2513 meson.current_source_dir() / 'scripts/qapi/gen.py', 2514 meson.current_source_dir() / 'scripts/qapi/introspect.py', 2515 meson.current_source_dir() / 'scripts/qapi/parser.py', 2516 meson.current_source_dir() / 'scripts/qapi/schema.py', 2517 meson.current_source_dir() / 'scripts/qapi/source.py', 2518 meson.current_source_dir() / 'scripts/qapi/types.py', 2519 meson.current_source_dir() / 'scripts/qapi/visit.py', 2520 meson.current_source_dir() / 'scripts/qapi/common.py', 2521 meson.current_source_dir() / 'scripts/qapi-gen.py' 2522] 2523 2524tracetool = [ 2525 python, files('scripts/tracetool.py'), 2526 '--backend=' + ','.join(get_option('trace_backends')) 2527] 2528tracetool_depends = files( 2529 'scripts/tracetool/backend/log.py', 2530 'scripts/tracetool/backend/__init__.py', 2531 'scripts/tracetool/backend/dtrace.py', 2532 'scripts/tracetool/backend/ftrace.py', 2533 'scripts/tracetool/backend/simple.py', 2534 'scripts/tracetool/backend/syslog.py', 2535 'scripts/tracetool/backend/ust.py', 2536 'scripts/tracetool/format/ust_events_c.py', 2537 'scripts/tracetool/format/ust_events_h.py', 2538 'scripts/tracetool/format/__init__.py', 2539 'scripts/tracetool/format/d.py', 2540 'scripts/tracetool/format/simpletrace_stap.py', 2541 'scripts/tracetool/format/c.py', 2542 'scripts/tracetool/format/h.py', 2543 'scripts/tracetool/format/log_stap.py', 2544 'scripts/tracetool/format/stap.py', 2545 'scripts/tracetool/__init__.py', 2546 'scripts/tracetool/transform.py', 2547 'scripts/tracetool/vcpu.py' 2548) 2549 2550qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 2551 meson.current_source_dir(), 2552 config_host['PKGVERSION'], meson.project_version()] 2553qemu_version = custom_target('qemu-version.h', 2554 output: 'qemu-version.h', 2555 command: qemu_version_cmd, 2556 capture: true, 2557 build_by_default: true, 2558 build_always_stale: true) 2559genh += qemu_version 2560 2561hxdep = [] 2562hx_headers = [ 2563 ['qemu-options.hx', 'qemu-options.def'], 2564 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 2565] 2566if have_system 2567 hx_headers += [ 2568 ['hmp-commands.hx', 'hmp-commands.h'], 2569 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 2570 ] 2571endif 2572foreach d : hx_headers 2573 hxdep += custom_target(d[1], 2574 input: files(d[0]), 2575 output: d[1], 2576 capture: true, 2577 build_by_default: true, # to be removed when added to a target 2578 command: [hxtool, '-h', '@INPUT0@']) 2579endforeach 2580genh += hxdep 2581 2582################### 2583# Collect sources # 2584################### 2585 2586authz_ss = ss.source_set() 2587blockdev_ss = ss.source_set() 2588block_ss = ss.source_set() 2589chardev_ss = ss.source_set() 2590common_ss = ss.source_set() 2591crypto_ss = ss.source_set() 2592hwcore_ss = ss.source_set() 2593io_ss = ss.source_set() 2594qmp_ss = ss.source_set() 2595qom_ss = ss.source_set() 2596softmmu_ss = ss.source_set() 2597specific_fuzz_ss = ss.source_set() 2598specific_ss = ss.source_set() 2599stub_ss = ss.source_set() 2600trace_ss = ss.source_set() 2601user_ss = ss.source_set() 2602util_ss = ss.source_set() 2603 2604# accel modules 2605qtest_module_ss = ss.source_set() 2606tcg_module_ss = ss.source_set() 2607 2608modules = {} 2609target_modules = {} 2610hw_arch = {} 2611target_arch = {} 2612target_softmmu_arch = {} 2613target_user_arch = {} 2614 2615############### 2616# Trace files # 2617############### 2618 2619# TODO: add each directory to the subdirs from its own meson.build, once 2620# we have those 2621trace_events_subdirs = [ 2622 'crypto', 2623 'qapi', 2624 'qom', 2625 'monitor', 2626 'util', 2627] 2628if have_linux_user 2629 trace_events_subdirs += [ 'linux-user' ] 2630endif 2631if have_bsd_user 2632 trace_events_subdirs += [ 'bsd-user' ] 2633endif 2634if have_block 2635 trace_events_subdirs += [ 2636 'authz', 2637 'block', 2638 'io', 2639 'nbd', 2640 'scsi', 2641 ] 2642endif 2643if have_system 2644 trace_events_subdirs += [ 2645 'accel/kvm', 2646 'audio', 2647 'backends', 2648 'backends/tpm', 2649 'chardev', 2650 'ebpf', 2651 'hw/9pfs', 2652 'hw/acpi', 2653 'hw/adc', 2654 'hw/alpha', 2655 'hw/arm', 2656 'hw/audio', 2657 'hw/block', 2658 'hw/block/dataplane', 2659 'hw/char', 2660 'hw/display', 2661 'hw/dma', 2662 'hw/hppa', 2663 'hw/hyperv', 2664 'hw/i2c', 2665 'hw/i386', 2666 'hw/i386/xen', 2667 'hw/ide', 2668 'hw/input', 2669 'hw/intc', 2670 'hw/isa', 2671 'hw/mem', 2672 'hw/mips', 2673 'hw/misc', 2674 'hw/misc/macio', 2675 'hw/net', 2676 'hw/net/can', 2677 'hw/nubus', 2678 'hw/nvme', 2679 'hw/nvram', 2680 'hw/pci', 2681 'hw/pci-host', 2682 'hw/ppc', 2683 'hw/rdma', 2684 'hw/rdma/vmw', 2685 'hw/rtc', 2686 'hw/s390x', 2687 'hw/scsi', 2688 'hw/sd', 2689 'hw/sh4', 2690 'hw/sparc', 2691 'hw/sparc64', 2692 'hw/ssi', 2693 'hw/timer', 2694 'hw/tpm', 2695 'hw/usb', 2696 'hw/vfio', 2697 'hw/virtio', 2698 'hw/watchdog', 2699 'hw/xen', 2700 'hw/gpio', 2701 'migration', 2702 'net', 2703 'softmmu', 2704 'ui', 2705 'hw/remote', 2706 ] 2707endif 2708if have_system or have_user 2709 trace_events_subdirs += [ 2710 'accel/tcg', 2711 'hw/core', 2712 'target/arm', 2713 'target/arm/hvf', 2714 'target/hppa', 2715 'target/i386', 2716 'target/i386/kvm', 2717 'target/mips/tcg', 2718 'target/nios2', 2719 'target/ppc', 2720 'target/riscv', 2721 'target/s390x', 2722 'target/s390x/kvm', 2723 'target/sparc', 2724 ] 2725endif 2726 2727vhost_user = not_found 2728if 'CONFIG_VHOST_USER' in config_host 2729 libvhost_user = subproject('libvhost-user') 2730 vhost_user = libvhost_user.get_variable('vhost_user_dep') 2731endif 2732 2733# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 2734# that is filled in by qapi/. 2735subdir('qapi') 2736subdir('qobject') 2737subdir('stubs') 2738subdir('trace') 2739subdir('util') 2740subdir('qom') 2741subdir('authz') 2742subdir('crypto') 2743subdir('ui') 2744 2745 2746if enable_modules 2747 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 2748 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 2749endif 2750 2751stub_ss = stub_ss.apply(config_all, strict: false) 2752 2753util_ss.add_all(trace_ss) 2754util_ss = util_ss.apply(config_all, strict: false) 2755libqemuutil = static_library('qemuutil', 2756 sources: util_ss.sources() + stub_ss.sources() + genh, 2757 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman]) 2758qemuutil = declare_dependency(link_with: libqemuutil, 2759 sources: genh + version_res) 2760 2761if have_system or have_user 2762 decodetree = generator(find_program('scripts/decodetree.py'), 2763 output: 'decode-@BASENAME@.c.inc', 2764 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 2765 subdir('libdecnumber') 2766 subdir('target') 2767endif 2768 2769subdir('audio') 2770subdir('io') 2771subdir('chardev') 2772subdir('fsdev') 2773subdir('dump') 2774 2775if have_block 2776 block_ss.add(files( 2777 'block.c', 2778 'blockjob.c', 2779 'job.c', 2780 'qemu-io-cmds.c', 2781 )) 2782 if config_host_data.get('CONFIG_REPLICATION') 2783 block_ss.add(files('replication.c')) 2784 endif 2785 2786 subdir('nbd') 2787 subdir('scsi') 2788 subdir('block') 2789 2790 blockdev_ss.add(files( 2791 'blockdev.c', 2792 'blockdev-nbd.c', 2793 'iothread.c', 2794 'job-qmp.c', 2795 ), gnutls) 2796 2797 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 2798 # os-win32.c does not 2799 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 2800 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 2801endif 2802 2803common_ss.add(files('cpus-common.c')) 2804 2805subdir('softmmu') 2806 2807common_ss.add(capstone) 2808specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone) 2809 2810# Work around a gcc bug/misfeature wherein constant propagation looks 2811# through an alias: 2812# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 2813# to guess that a const variable is always zero. Without lto, this is 2814# impossible, as the alias is restricted to page-vary-common.c. Indeed, 2815# without lto, not even the alias is required -- we simply use different 2816# declarations in different compilation units. 2817pagevary = files('page-vary-common.c') 2818if get_option('b_lto') 2819 pagevary_flags = ['-fno-lto'] 2820 if get_option('cfi') 2821 pagevary_flags += '-fno-sanitize=cfi-icall' 2822 endif 2823 pagevary = static_library('page-vary-common', sources: pagevary, 2824 c_args: pagevary_flags) 2825 pagevary = declare_dependency(link_with: pagevary) 2826endif 2827common_ss.add(pagevary) 2828specific_ss.add(files('page-vary.c')) 2829 2830subdir('backends') 2831subdir('disas') 2832subdir('migration') 2833subdir('monitor') 2834subdir('net') 2835subdir('replay') 2836subdir('semihosting') 2837subdir('hw') 2838subdir('tcg') 2839subdir('fpu') 2840subdir('accel') 2841subdir('plugins') 2842subdir('ebpf') 2843 2844common_user_inc = [] 2845 2846subdir('common-user') 2847subdir('bsd-user') 2848subdir('linux-user') 2849 2850# needed for fuzzing binaries 2851subdir('tests/qtest/libqos') 2852subdir('tests/qtest/fuzz') 2853 2854# accel modules 2855tcg_real_module_ss = ss.source_set() 2856tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 2857specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 2858target_modules += { 'accel' : { 'qtest': qtest_module_ss, 2859 'tcg': tcg_real_module_ss }} 2860 2861######################## 2862# Library dependencies # 2863######################## 2864 2865modinfo_collect = find_program('scripts/modinfo-collect.py') 2866modinfo_generate = find_program('scripts/modinfo-generate.py') 2867modinfo_files = [] 2868 2869block_mods = [] 2870softmmu_mods = [] 2871foreach d, list : modules 2872 foreach m, module_ss : list 2873 if enable_modules and targetos != 'windows' 2874 module_ss = module_ss.apply(config_all, strict: false) 2875 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 2876 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 2877 if d == 'block' 2878 block_mods += sl 2879 else 2880 softmmu_mods += sl 2881 endif 2882 if module_ss.sources() != [] 2883 # FIXME: Should use sl.extract_all_objects(recursive: true) as 2884 # input. Sources can be used multiple times but objects are 2885 # unique when it comes to lookup in compile_commands.json. 2886 # Depnds on a mesion version with 2887 # https://github.com/mesonbuild/meson/pull/8900 2888 modinfo_files += custom_target(d + '-' + m + '.modinfo', 2889 output: d + '-' + m + '.modinfo', 2890 input: module_ss.sources() + genh, 2891 capture: true, 2892 command: [modinfo_collect, module_ss.sources()]) 2893 endif 2894 else 2895 if d == 'block' 2896 block_ss.add_all(module_ss) 2897 else 2898 softmmu_ss.add_all(module_ss) 2899 endif 2900 endif 2901 endforeach 2902endforeach 2903 2904foreach d, list : target_modules 2905 foreach m, module_ss : list 2906 if enable_modules and targetos != 'windows' 2907 foreach target : target_dirs 2908 if target.endswith('-softmmu') 2909 config_target = config_target_mak[target] 2910 config_target += config_host 2911 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 2912 c_args = ['-DNEED_CPU_H', 2913 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 2914 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 2915 target_module_ss = module_ss.apply(config_target, strict: false) 2916 if target_module_ss.sources() != [] 2917 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 2918 sl = static_library(module_name, 2919 [genh, target_module_ss.sources()], 2920 dependencies: [modulecommon, target_module_ss.dependencies()], 2921 include_directories: target_inc, 2922 c_args: c_args, 2923 pic: true) 2924 softmmu_mods += sl 2925 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 2926 modinfo_files += custom_target(module_name + '.modinfo', 2927 output: module_name + '.modinfo', 2928 input: target_module_ss.sources() + genh, 2929 capture: true, 2930 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 2931 endif 2932 endif 2933 endforeach 2934 else 2935 specific_ss.add_all(module_ss) 2936 endif 2937 endforeach 2938endforeach 2939 2940if enable_modules 2941 modinfo_src = custom_target('modinfo.c', 2942 output: 'modinfo.c', 2943 input: modinfo_files, 2944 command: [modinfo_generate, '@INPUT@'], 2945 capture: true) 2946 modinfo_lib = static_library('modinfo', modinfo_src) 2947 modinfo_dep = declare_dependency(link_whole: modinfo_lib) 2948 softmmu_ss.add(modinfo_dep) 2949endif 2950 2951nm = find_program('nm') 2952undefsym = find_program('scripts/undefsym.py') 2953block_syms = custom_target('block.syms', output: 'block.syms', 2954 input: [libqemuutil, block_mods], 2955 capture: true, 2956 command: [undefsym, nm, '@INPUT@']) 2957qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 2958 input: [libqemuutil, softmmu_mods], 2959 capture: true, 2960 command: [undefsym, nm, '@INPUT@']) 2961 2962qom_ss = qom_ss.apply(config_host, strict: false) 2963libqom = static_library('qom', qom_ss.sources() + genh, 2964 dependencies: [qom_ss.dependencies()], 2965 name_suffix: 'fa') 2966 2967qom = declare_dependency(link_whole: libqom) 2968 2969authz_ss = authz_ss.apply(config_host, strict: false) 2970libauthz = static_library('authz', authz_ss.sources() + genh, 2971 dependencies: [authz_ss.dependencies()], 2972 name_suffix: 'fa', 2973 build_by_default: false) 2974 2975authz = declare_dependency(link_whole: libauthz, 2976 dependencies: qom) 2977 2978crypto_ss = crypto_ss.apply(config_host, strict: false) 2979libcrypto = static_library('crypto', crypto_ss.sources() + genh, 2980 dependencies: [crypto_ss.dependencies()], 2981 name_suffix: 'fa', 2982 build_by_default: false) 2983 2984crypto = declare_dependency(link_whole: libcrypto, 2985 dependencies: [authz, qom]) 2986 2987io_ss = io_ss.apply(config_host, strict: false) 2988libio = static_library('io', io_ss.sources() + genh, 2989 dependencies: [io_ss.dependencies()], 2990 link_with: libqemuutil, 2991 name_suffix: 'fa', 2992 build_by_default: false) 2993 2994io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 2995 2996libmigration = static_library('migration', sources: migration_files + genh, 2997 name_suffix: 'fa', 2998 build_by_default: false) 2999migration = declare_dependency(link_with: libmigration, 3000 dependencies: [zlib, qom, io]) 3001softmmu_ss.add(migration) 3002 3003block_ss = block_ss.apply(config_host, strict: false) 3004libblock = static_library('block', block_ss.sources() + genh, 3005 dependencies: block_ss.dependencies(), 3006 link_depends: block_syms, 3007 name_suffix: 'fa', 3008 build_by_default: false) 3009 3010block = declare_dependency(link_whole: [libblock], 3011 link_args: '@block.syms', 3012 dependencies: [crypto, io]) 3013 3014blockdev_ss = blockdev_ss.apply(config_host, strict: false) 3015libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3016 dependencies: blockdev_ss.dependencies(), 3017 name_suffix: 'fa', 3018 build_by_default: false) 3019 3020blockdev = declare_dependency(link_whole: [libblockdev], 3021 dependencies: [block]) 3022 3023qmp_ss = qmp_ss.apply(config_host, strict: false) 3024libqmp = static_library('qmp', qmp_ss.sources() + genh, 3025 dependencies: qmp_ss.dependencies(), 3026 name_suffix: 'fa', 3027 build_by_default: false) 3028 3029qmp = declare_dependency(link_whole: [libqmp]) 3030 3031libchardev = static_library('chardev', chardev_ss.sources() + genh, 3032 name_suffix: 'fa', 3033 dependencies: [gnutls], 3034 build_by_default: false) 3035 3036chardev = declare_dependency(link_whole: libchardev) 3037 3038hwcore_ss = hwcore_ss.apply(config_host, strict: false) 3039libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3040 name_suffix: 'fa', 3041 build_by_default: false) 3042hwcore = declare_dependency(link_whole: libhwcore) 3043common_ss.add(hwcore) 3044 3045########### 3046# Targets # 3047########### 3048 3049emulator_modules = [] 3050foreach m : block_mods + softmmu_mods 3051 emulator_modules += shared_module(m.name(), 3052 build_by_default: true, 3053 name_prefix: '', 3054 link_whole: m, 3055 install: true, 3056 install_dir: qemu_moddir) 3057endforeach 3058 3059softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3060common_ss.add(qom, qemuutil) 3061 3062common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 3063common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3064 3065common_all = common_ss.apply(config_all, strict: false) 3066common_all = static_library('common', 3067 build_by_default: false, 3068 sources: common_all.sources() + genh, 3069 include_directories: common_user_inc, 3070 implicit_include_directories: false, 3071 dependencies: common_all.dependencies(), 3072 name_suffix: 'fa') 3073 3074feature_to_c = find_program('scripts/feature_to_c.sh') 3075 3076emulators = {} 3077foreach target : target_dirs 3078 config_target = config_target_mak[target] 3079 target_name = config_target['TARGET_NAME'] 3080 target_base_arch = config_target['TARGET_BASE_ARCH'] 3081 arch_srcs = [config_target_h[target]] 3082 arch_deps = [] 3083 c_args = ['-DNEED_CPU_H', 3084 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3085 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3086 link_args = emulator_link_args 3087 3088 config_target += config_host 3089 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3090 if targetos == 'linux' 3091 target_inc += include_directories('linux-headers', is_system: true) 3092 endif 3093 if target.endswith('-softmmu') 3094 qemu_target_name = 'qemu-system-' + target_name 3095 target_type='system' 3096 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false) 3097 arch_srcs += t.sources() 3098 arch_deps += t.dependencies() 3099 3100 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3101 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3102 arch_srcs += hw.sources() 3103 arch_deps += hw.dependencies() 3104 3105 arch_srcs += config_devices_h[target] 3106 link_args += ['@block.syms', '@qemu.syms'] 3107 else 3108 abi = config_target['TARGET_ABI_DIR'] 3109 target_type='user' 3110 target_inc += common_user_inc 3111 qemu_target_name = 'qemu-' + target_name 3112 if target_base_arch in target_user_arch 3113 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3114 arch_srcs += t.sources() 3115 arch_deps += t.dependencies() 3116 endif 3117 if 'CONFIG_LINUX_USER' in config_target 3118 base_dir = 'linux-user' 3119 endif 3120 if 'CONFIG_BSD_USER' in config_target 3121 base_dir = 'bsd-user' 3122 target_inc += include_directories('bsd-user/' / targetos) 3123 target_inc += include_directories('bsd-user/host/' / host_arch) 3124 dir = base_dir / abi 3125 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3126 endif 3127 target_inc += include_directories( 3128 base_dir, 3129 base_dir / abi, 3130 ) 3131 if 'CONFIG_LINUX_USER' in config_target 3132 dir = base_dir / abi 3133 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3134 if config_target.has_key('TARGET_SYSTBL_ABI') 3135 arch_srcs += \ 3136 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3137 extra_args : config_target['TARGET_SYSTBL_ABI']) 3138 endif 3139 endif 3140 endif 3141 3142 if 'TARGET_XML_FILES' in config_target 3143 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3144 output: target + '-gdbstub-xml.c', 3145 input: files(config_target['TARGET_XML_FILES'].split()), 3146 command: [feature_to_c, '@INPUT@'], 3147 capture: true) 3148 arch_srcs += gdbstub_xml 3149 endif 3150 3151 t = target_arch[target_base_arch].apply(config_target, strict: false) 3152 arch_srcs += t.sources() 3153 arch_deps += t.dependencies() 3154 3155 target_common = common_ss.apply(config_target, strict: false) 3156 objects = common_all.extract_objects(target_common.sources()) 3157 deps = target_common.dependencies() 3158 3159 target_specific = specific_ss.apply(config_target, strict: false) 3160 arch_srcs += target_specific.sources() 3161 arch_deps += target_specific.dependencies() 3162 3163 lib = static_library('qemu-' + target, 3164 sources: arch_srcs + genh, 3165 dependencies: arch_deps, 3166 objects: objects, 3167 include_directories: target_inc, 3168 c_args: c_args, 3169 build_by_default: false, 3170 name_suffix: 'fa') 3171 3172 if target.endswith('-softmmu') 3173 execs = [{ 3174 'name': 'qemu-system-' + target_name, 3175 'win_subsystem': 'console', 3176 'sources': files('softmmu/main.c'), 3177 'dependencies': [] 3178 }] 3179 if targetos == 'windows' and (sdl.found() or gtk.found()) 3180 execs += [{ 3181 'name': 'qemu-system-' + target_name + 'w', 3182 'win_subsystem': 'windows', 3183 'sources': files('softmmu/main.c'), 3184 'dependencies': [] 3185 }] 3186 endif 3187 if get_option('fuzzing') 3188 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 3189 execs += [{ 3190 'name': 'qemu-fuzz-' + target_name, 3191 'win_subsystem': 'console', 3192 'sources': specific_fuzz.sources(), 3193 'dependencies': specific_fuzz.dependencies(), 3194 }] 3195 endif 3196 else 3197 execs = [{ 3198 'name': 'qemu-' + target_name, 3199 'win_subsystem': 'console', 3200 'sources': [], 3201 'dependencies': [] 3202 }] 3203 endif 3204 foreach exe: execs 3205 exe_name = exe['name'] 3206 if targetos == 'darwin' 3207 exe_name += '-unsigned' 3208 endif 3209 3210 emulator = executable(exe_name, exe['sources'], 3211 install: true, 3212 c_args: c_args, 3213 dependencies: arch_deps + deps + exe['dependencies'], 3214 objects: lib.extract_all_objects(recursive: true), 3215 link_language: link_language, 3216 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 3217 link_args: link_args, 3218 win_subsystem: exe['win_subsystem']) 3219 3220 if targetos == 'darwin' 3221 icon = 'pc-bios/qemu.rsrc' 3222 build_input = [emulator, files(icon)] 3223 install_input = [ 3224 get_option('bindir') / exe_name, 3225 meson.current_source_dir() / icon 3226 ] 3227 if 'CONFIG_HVF' in config_target 3228 entitlements = 'accel/hvf/entitlements.plist' 3229 build_input += files(entitlements) 3230 install_input += meson.current_source_dir() / entitlements 3231 endif 3232 3233 entitlement = find_program('scripts/entitlement.sh') 3234 emulators += {exe['name'] : custom_target(exe['name'], 3235 input: build_input, 3236 output: exe['name'], 3237 command: [entitlement, '@OUTPUT@', '@INPUT@']) 3238 } 3239 3240 meson.add_install_script(entitlement, '--install', 3241 get_option('bindir') / exe['name'], 3242 install_input) 3243 else 3244 emulators += {exe['name']: emulator} 3245 endif 3246 3247 if stap.found() 3248 foreach stp: [ 3249 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 3250 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 3251 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 3252 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 3253 ] 3254 custom_target(exe['name'] + stp['ext'], 3255 input: trace_events_all, 3256 output: exe['name'] + stp['ext'], 3257 install: stp['install'], 3258 install_dir: get_option('datadir') / 'systemtap/tapset', 3259 command: [ 3260 tracetool, '--group=all', '--format=' + stp['fmt'], 3261 '--binary=' + stp['bin'], 3262 '--target-name=' + target_name, 3263 '--target-type=' + target_type, 3264 '--probe-prefix=qemu.' + target_type + '.' + target_name, 3265 '@INPUT@', '@OUTPUT@' 3266 ], 3267 depend_files: tracetool_depends) 3268 endforeach 3269 endif 3270 endforeach 3271endforeach 3272 3273# Other build targets 3274 3275if 'CONFIG_PLUGIN' in config_host 3276 install_headers('include/qemu/qemu-plugin.h') 3277endif 3278 3279subdir('qga') 3280 3281# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3282# when we don't build tools or system 3283if xkbcommon.found() 3284 # used for the update-keymaps target, so include rules even if !have_tools 3285 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 3286 dependencies: [qemuutil, xkbcommon], install: have_tools) 3287endif 3288 3289if have_tools 3290 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 3291 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 3292 qemu_io = executable('qemu-io', files('qemu-io.c'), 3293 dependencies: [block, qemuutil], install: true) 3294 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 3295 dependencies: [blockdev, qemuutil, gnutls, selinux], 3296 install: true) 3297 3298 subdir('storage-daemon') 3299 subdir('contrib/rdmacm-mux') 3300 subdir('contrib/elf2dmp') 3301 3302 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 3303 dependencies: qemuutil, 3304 install: true) 3305 3306 if 'CONFIG_VHOST_USER' in config_host 3307 subdir('contrib/vhost-user-blk') 3308 subdir('contrib/vhost-user-gpu') 3309 subdir('contrib/vhost-user-input') 3310 subdir('contrib/vhost-user-scsi') 3311 endif 3312 3313 if targetos == 'linux' 3314 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 3315 dependencies: [qemuutil, libcap_ng], 3316 install: true, 3317 install_dir: get_option('libexecdir')) 3318 3319 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 3320 dependencies: [authz, crypto, io, qom, qemuutil, 3321 libcap_ng, mpathpersist], 3322 install: true) 3323 endif 3324 3325 if have_ivshmem 3326 subdir('contrib/ivshmem-client') 3327 subdir('contrib/ivshmem-server') 3328 endif 3329endif 3330 3331subdir('scripts') 3332subdir('tools') 3333subdir('pc-bios') 3334subdir('docs') 3335subdir('tests') 3336if gtk.found() 3337 subdir('po') 3338endif 3339 3340if host_machine.system() == 'windows' 3341 nsis_cmd = [ 3342 find_program('scripts/nsis.py'), 3343 '@OUTPUT@', 3344 get_option('prefix'), 3345 meson.current_source_dir(), 3346 host_machine.cpu(), 3347 '--', 3348 '-DDISPLAYVERSION=' + meson.project_version(), 3349 ] 3350 if build_docs 3351 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 3352 endif 3353 if gtk.found() 3354 nsis_cmd += '-DCONFIG_GTK=y' 3355 endif 3356 3357 nsis = custom_target('nsis', 3358 output: 'qemu-setup-' + meson.project_version() + '.exe', 3359 input: files('qemu.nsi'), 3360 build_always_stale: true, 3361 command: nsis_cmd + ['@INPUT@']) 3362 alias_target('installer', nsis) 3363endif 3364 3365######################### 3366# Configuration summary # 3367######################### 3368 3369# Directories 3370summary_info = {} 3371summary_info += {'Install prefix': get_option('prefix')} 3372summary_info += {'BIOS directory': qemu_datadir} 3373summary_info += {'firmware path': get_option('qemu_firmwarepath')} 3374summary_info += {'binary directory': get_option('bindir')} 3375summary_info += {'library directory': get_option('libdir')} 3376summary_info += {'module directory': qemu_moddir} 3377summary_info += {'libexec directory': get_option('libexecdir')} 3378summary_info += {'include directory': get_option('includedir')} 3379summary_info += {'config directory': get_option('sysconfdir')} 3380if targetos != 'windows' 3381 summary_info += {'local state directory': get_option('localstatedir')} 3382 summary_info += {'Manual directory': get_option('mandir')} 3383else 3384 summary_info += {'local state directory': 'queried at runtime'} 3385endif 3386summary_info += {'Doc directory': get_option('docdir')} 3387summary_info += {'Build directory': meson.current_build_dir()} 3388summary_info += {'Source path': meson.current_source_dir()} 3389summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 3390summary(summary_info, bool_yn: true, section: 'Directories') 3391 3392# Host binaries 3393summary_info = {} 3394summary_info += {'git': config_host['GIT']} 3395summary_info += {'make': config_host['MAKE']} 3396summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 3397summary_info += {'sphinx-build': sphinx_build} 3398if config_host.has_key('HAVE_GDB_BIN') 3399 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 3400endif 3401if get_option('iasl') != '' 3402 summary_info += {'iasl': get_option('iasl')} 3403else 3404 summary_info += {'iasl': false} 3405endif 3406summary_info += {'genisoimage': config_host['GENISOIMAGE']} 3407if targetos == 'windows' and have_ga 3408 summary_info += {'wixl': wixl} 3409endif 3410if slirp_opt != 'disabled' and have_system 3411 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 3412endif 3413summary(summary_info, bool_yn: true, section: 'Host binaries') 3414 3415# Configurable features 3416summary_info = {} 3417summary_info += {'Documentation': build_docs} 3418summary_info += {'system-mode emulation': have_system} 3419summary_info += {'user-mode emulation': have_user} 3420summary_info += {'block layer': have_block} 3421summary_info += {'Install blobs': get_option('install_blobs')} 3422summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} 3423if config_host.has_key('CONFIG_MODULES') 3424 summary_info += {'alternative module path': config_host.has_key('CONFIG_MODULE_UPGRADES')} 3425endif 3426summary_info += {'fuzzing support': get_option('fuzzing')} 3427if have_system 3428 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 3429endif 3430summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 3431if 'simple' in get_option('trace_backends') 3432 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 3433endif 3434summary_info += {'D-Bus display': dbus_display} 3435summary_info += {'QOM debugging': get_option('qom_cast_debug')} 3436summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')} 3437summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} 3438summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} 3439summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')} 3440summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')} 3441summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')} 3442summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 3443summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')} 3444summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')} 3445summary_info += {'build guest agent': have_ga} 3446summary(summary_info, bool_yn: true, section: 'Configurable features') 3447 3448# Compilation information 3449summary_info = {} 3450summary_info += {'host CPU': cpu} 3451summary_info += {'host endianness': build_machine.endian()} 3452summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 3453summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 3454if link_language == 'cpp' 3455 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 3456else 3457 summary_info += {'C++ compiler': false} 3458endif 3459if targetos == 'darwin' 3460 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 3461endif 3462summary_info += {'CFLAGS': ' '.join(get_option('c_args') 3463 + ['-O' + get_option('optimization')] 3464 + (get_option('debug') ? ['-g'] : []))} 3465if link_language == 'cpp' 3466 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') 3467 + ['-O' + get_option('optimization')] 3468 + (get_option('debug') ? ['-g'] : []))} 3469endif 3470link_args = get_option(link_language + '_link_args') 3471if link_args.length() > 0 3472 summary_info += {'LDFLAGS': ' '.join(link_args)} 3473endif 3474summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']} 3475summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']} 3476summary_info += {'profiler': get_option('profiler')} 3477summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 3478summary_info += {'PIE': get_option('b_pie')} 3479summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 3480summary_info += {'malloc trim support': has_malloc_trim} 3481summary_info += {'membarrier': have_membarrier} 3482summary_info += {'debug stack usage': get_option('debug_stack_usage')} 3483summary_info += {'mutex debugging': get_option('debug_mutex')} 3484summary_info += {'memory allocator': get_option('malloc')} 3485summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 3486summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 3487summary_info += {'gprof enabled': get_option('gprof')} 3488summary_info += {'gcov': get_option('b_coverage')} 3489summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} 3490summary_info += {'CFI support': get_option('cfi')} 3491if get_option('cfi') 3492 summary_info += {'CFI debug support': get_option('cfi_debug')} 3493endif 3494summary_info += {'strip binaries': get_option('strip')} 3495summary_info += {'sparse': sparse} 3496summary_info += {'mingw32 support': targetos == 'windows'} 3497 3498# snarf the cross-compilation information for tests 3499foreach target: target_dirs 3500 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak' 3501 if fs.exists(tcg_mak) 3502 config_cross_tcg = keyval.load(tcg_mak) 3503 target = config_cross_tcg['TARGET_NAME'] 3504 compiler = '' 3505 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg 3506 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] + 3507 ' via ' + config_cross_tcg['DOCKER_IMAGE']} 3508 elif 'CROSS_CC_GUEST' in config_cross_tcg 3509 summary_info += {target + ' tests' 3510 : config_cross_tcg['CROSS_CC_GUEST'] } 3511 endif 3512 endif 3513endforeach 3514 3515summary(summary_info, bool_yn: true, section: 'Compilation') 3516 3517# Targets and accelerators 3518summary_info = {} 3519if have_system 3520 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 3521 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 3522 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 3523 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 3524 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')} 3525 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')} 3526 if config_host.has_key('CONFIG_XEN_BACKEND') 3527 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} 3528 endif 3529endif 3530summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 3531if config_all.has_key('CONFIG_TCG') 3532 if get_option('tcg_interpreter') 3533 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 3534 else 3535 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 3536 endif 3537 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')} 3538 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 3539endif 3540summary_info += {'target list': ' '.join(target_dirs)} 3541if have_system 3542 summary_info += {'default devices': get_option('default_devices')} 3543 summary_info += {'out of process emulation': multiprocess_allowed} 3544endif 3545summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 3546 3547# Block layer 3548summary_info = {} 3549summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} 3550summary_info += {'coroutine pool': have_coroutine_pool} 3551if have_block 3552 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} 3553 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} 3554 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 3555 summary_info += {'VirtFS support': have_virtfs} 3556 summary_info += {'build virtiofs daemon': have_virtiofsd} 3557 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')} 3558 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 3559 summary_info += {'bochs support': get_option('bochs').allowed()} 3560 summary_info += {'cloop support': get_option('cloop').allowed()} 3561 summary_info += {'dmg support': get_option('dmg').allowed()} 3562 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 3563 summary_info += {'vdi support': get_option('vdi').allowed()} 3564 summary_info += {'vvfat support': get_option('vvfat').allowed()} 3565 summary_info += {'qed support': get_option('qed').allowed()} 3566 summary_info += {'parallels support': get_option('parallels').allowed()} 3567 summary_info += {'FUSE exports': fuse} 3568endif 3569summary(summary_info, bool_yn: true, section: 'Block layer support') 3570 3571# Crypto 3572summary_info = {} 3573summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']} 3574summary_info += {'GNUTLS support': gnutls} 3575if gnutls.found() 3576 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 3577endif 3578summary_info += {'libgcrypt': gcrypt} 3579summary_info += {'nettle': nettle} 3580if nettle.found() 3581 summary_info += {' XTS': xts != 'private'} 3582endif 3583summary_info += {'AF_ALG support': have_afalg} 3584summary_info += {'rng-none': get_option('rng_none')} 3585summary_info += {'Linux keyring': config_host.has_key('CONFIG_SECRET_KEYRING')} 3586summary(summary_info, bool_yn: true, section: 'Crypto') 3587 3588# Libraries 3589summary_info = {} 3590if targetos == 'darwin' 3591 summary_info += {'Cocoa support': cocoa} 3592endif 3593summary_info += {'SDL support': sdl} 3594summary_info += {'SDL image support': sdl_image} 3595summary_info += {'GTK support': gtk} 3596summary_info += {'pixman': pixman} 3597summary_info += {'VTE support': vte} 3598summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp} 3599summary_info += {'libtasn1': tasn1} 3600summary_info += {'PAM': pam} 3601summary_info += {'iconv support': iconv} 3602summary_info += {'curses support': curses} 3603summary_info += {'virgl support': virgl} 3604summary_info += {'curl support': curl} 3605summary_info += {'Multipath support': mpathpersist} 3606summary_info += {'VNC support': vnc} 3607if vnc.found() 3608 summary_info += {'VNC SASL support': sasl} 3609 summary_info += {'VNC JPEG support': jpeg} 3610 summary_info += {'VNC PNG support': png} 3611endif 3612if targetos not in ['darwin', 'haiku', 'windows'] 3613 summary_info += {'OSS support': oss} 3614elif targetos == 'darwin' 3615 summary_info += {'CoreAudio support': coreaudio} 3616elif targetos == 'windows' 3617 summary_info += {'DirectSound support': dsound} 3618endif 3619if targetos == 'linux' 3620 summary_info += {'ALSA support': alsa} 3621 summary_info += {'PulseAudio support': pulse} 3622endif 3623summary_info += {'JACK support': jack} 3624summary_info += {'brlapi support': brlapi} 3625summary_info += {'vde support': vde} 3626summary_info += {'netmap support': have_netmap} 3627summary_info += {'l2tpv3 support': have_l2tpv3} 3628summary_info += {'Linux AIO support': libaio} 3629summary_info += {'Linux io_uring support': linux_io_uring} 3630summary_info += {'ATTR/XATTR support': libattr} 3631summary_info += {'RDMA support': config_host.has_key('CONFIG_RDMA')} 3632summary_info += {'PVRDMA support': config_host.has_key('CONFIG_PVRDMA')} 3633summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 3634summary_info += {'libcap-ng support': libcap_ng} 3635summary_info += {'bpf support': libbpf} 3636summary_info += {'spice protocol support': spice_protocol} 3637if spice_protocol.found() 3638 summary_info += {' spice server support': spice} 3639endif 3640summary_info += {'rbd support': rbd} 3641summary_info += {'smartcard support': cacard} 3642summary_info += {'U2F support': u2f} 3643summary_info += {'libusb': libusb} 3644summary_info += {'usb net redir': usbredir} 3645summary_info += {'OpenGL support': config_host.has_key('CONFIG_OPENGL')} 3646summary_info += {'GBM': gbm} 3647summary_info += {'libiscsi support': libiscsi} 3648summary_info += {'libnfs support': libnfs} 3649if targetos == 'windows' 3650 if have_ga 3651 summary_info += {'QGA VSS support': have_qga_vss} 3652 summary_info += {'QGA w32 disk info': have_ntddscsi} 3653 endif 3654endif 3655summary_info += {'seccomp support': seccomp} 3656summary_info += {'GlusterFS support': glusterfs} 3657summary_info += {'TPM support': have_tpm} 3658summary_info += {'libssh support': libssh} 3659summary_info += {'lzo support': lzo} 3660summary_info += {'snappy support': snappy} 3661summary_info += {'bzip2 support': libbzip2} 3662summary_info += {'lzfse support': liblzfse} 3663summary_info += {'zstd support': zstd} 3664summary_info += {'NUMA host support': numa} 3665summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone} 3666summary_info += {'libpmem support': libpmem} 3667summary_info += {'libdaxctl support': libdaxctl} 3668summary_info += {'libudev': libudev} 3669# Dummy dependency, keep .found() 3670summary_info += {'FUSE lseek': fuse_lseek.found()} 3671summary_info += {'selinux': selinux} 3672summary(summary_info, bool_yn: true, section: 'Dependencies') 3673 3674if not supported_cpus.contains(cpu) 3675 message() 3676 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 3677 message() 3678 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 3679 message('The QEMU project intends to remove support for this host CPU in') 3680 message('a future release if nobody volunteers to maintain it and to') 3681 message('provide a build host for our continuous integration setup.') 3682 message('configure has succeeded and you can continue to build, but') 3683 message('if you care about QEMU on this platform you should contact') 3684 message('us upstream at qemu-devel@nongnu.org.') 3685endif 3686 3687if not supported_oses.contains(targetos) 3688 message() 3689 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 3690 message() 3691 message('Host OS ' + targetos + 'support is not currently maintained.') 3692 message('The QEMU project intends to remove support for this host OS in') 3693 message('a future release if nobody volunteers to maintain it and to') 3694 message('provide a build host for our continuous integration setup.') 3695 message('configure has succeeded and you can continue to build, but') 3696 message('if you care about QEMU on this platform you should contact') 3697 message('us upstream at qemu-devel@nongnu.org.') 3698endif 3699