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