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_GETIFADDRS', cc.has_function('getifaddrs')) 1691config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 1692config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 1693config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 1694if rdma.found() 1695 config_host_data.set('HAVE_IBV_ADVISE_MR', 1696 cc.has_function('ibv_advise_mr', 1697 dependencies: rdma, 1698 prefix: '#include <infiniband/verbs.h>')) 1699endif 1700 1701# has_header_symbol 1702config_host_data.set('CONFIG_BYTESWAP_H', 1703 cc.has_header_symbol('byteswap.h', 'bswap_32')) 1704config_host_data.set('CONFIG_EPOLL_CREATE1', 1705 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 1706config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 1707 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 1708 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 1709config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 1710 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 1711config_host_data.set('CONFIG_FIEMAP', 1712 cc.has_header('linux/fiemap.h') and 1713 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 1714config_host_data.set('CONFIG_GETRANDOM', 1715 cc.has_function('getrandom') and 1716 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 1717config_host_data.set('CONFIG_INOTIFY', 1718 cc.has_header_symbol('sys/inotify.h', 'inotify_init')) 1719config_host_data.set('CONFIG_INOTIFY1', 1720 cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) 1721config_host_data.set('CONFIG_MACHINE_BSWAP_H', 1722 cc.has_header_symbol('machine/bswap.h', 'bswap32', 1723 prefix: '''#include <sys/endian.h> 1724 #include <sys/types.h>''')) 1725config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 1726 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 1727config_host_data.set('CONFIG_RTNETLINK', 1728 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 1729config_host_data.set('CONFIG_SYSMACROS', 1730 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 1731config_host_data.set('HAVE_OPTRESET', 1732 cc.has_header_symbol('getopt.h', 'optreset')) 1733config_host_data.set('HAVE_IPPROTO_MPTCP', 1734 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 1735 1736# has_member 1737config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 1738 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 1739 prefix: '#include <signal.h>')) 1740config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 1741 cc.has_member('struct stat', 'st_atim', 1742 prefix: '#include <sys/stat.h>')) 1743 1744# has_type 1745config_host_data.set('CONFIG_IOVEC', 1746 cc.has_type('struct iovec', 1747 prefix: '#include <sys/uio.h>')) 1748config_host_data.set('HAVE_UTMPX', 1749 cc.has_type('struct utmpx', 1750 prefix: '#include <utmpx.h>')) 1751 1752config_host_data.set('CONFIG_EVENTFD', cc.links(''' 1753 #include <sys/eventfd.h> 1754 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 1755config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 1756 #include <unistd.h> 1757 int main(void) { 1758 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 1759 return fdatasync(0); 1760 #else 1761 #error Not supported 1762 #endif 1763 }''')) 1764 1765has_madvise = cc.links(gnu_source_prefix + ''' 1766 #include <sys/types.h> 1767 #include <sys/mman.h> 1768 #include <stddef.h> 1769 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 1770missing_madvise_proto = false 1771if has_madvise 1772 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 1773 # but forget to prototype it. In this case, has_madvise will be true (the 1774 # test program links despite a compile warning). To detect the 1775 # missing-prototype case, we try again with a definitely-bogus prototype. 1776 # This will only compile if the system headers don't provide the prototype; 1777 # otherwise the conflicting prototypes will cause a compiler error. 1778 missing_madvise_proto = cc.links(gnu_source_prefix + ''' 1779 #include <sys/types.h> 1780 #include <sys/mman.h> 1781 #include <stddef.h> 1782 extern int madvise(int); 1783 int main(void) { return madvise(0); }''') 1784endif 1785config_host_data.set('CONFIG_MADVISE', has_madvise) 1786config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 1787 1788config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 1789 #include <sys/mman.h> 1790 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 1791config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 1792 #include <fcntl.h> 1793 #if !defined(AT_EMPTY_PATH) 1794 # error missing definition 1795 #else 1796 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 1797 #endif''')) 1798config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + ''' 1799 #include <unistd.h> 1800 #include <fcntl.h> 1801 1802 int main(void) 1803 { 1804 int pipefd[2]; 1805 return pipe2(pipefd, O_CLOEXEC); 1806 }''')) 1807config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 1808 #include <sys/mman.h> 1809 #include <stddef.h> 1810 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 1811 1812config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 1813 #include <pthread.h> 1814 1815 static void *f(void *p) { return NULL; } 1816 int main(void) 1817 { 1818 pthread_t thread; 1819 pthread_create(&thread, 0, f, 0); 1820 pthread_setname_np(thread, "QEMU"); 1821 return 0; 1822 }''', dependencies: threads)) 1823config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 1824 #include <pthread.h> 1825 1826 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 1827 int main(void) 1828 { 1829 pthread_t thread; 1830 pthread_create(&thread, 0, f, 0); 1831 return 0; 1832 }''', dependencies: threads)) 1833config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + ''' 1834 #include <pthread.h> 1835 #include <time.h> 1836 1837 int main(void) 1838 { 1839 pthread_condattr_t attr 1840 pthread_condattr_init(&attr); 1841 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 1842 return 0; 1843 }''', dependencies: threads)) 1844 1845config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 1846 #include <sys/signalfd.h> 1847 #include <stddef.h> 1848 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 1849config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 1850 #include <unistd.h> 1851 #include <fcntl.h> 1852 #include <limits.h> 1853 1854 int main(void) 1855 { 1856 int len, fd = 0; 1857 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 1858 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 1859 return 0; 1860 }''')) 1861 1862config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 1863 #include <sys/mman.h> 1864 int main(int argc, char *argv[]) { 1865 return mlockall(MCL_FUTURE); 1866 }''')) 1867 1868have_l2tpv3 = false 1869if get_option('l2tpv3').allowed() and have_system 1870 have_l2tpv3 = cc.has_type('struct mmsghdr', 1871 prefix: gnu_source_prefix + ''' 1872 #include <sys/socket.h> 1873 #include <linux/ip.h>''') 1874endif 1875config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 1876 1877have_netmap = false 1878if get_option('netmap').allowed() and have_system 1879 have_netmap = cc.compiles(''' 1880 #include <inttypes.h> 1881 #include <net/if.h> 1882 #include <net/netmap.h> 1883 #include <net/netmap_user.h> 1884 #if (NETMAP_API < 11) || (NETMAP_API > 15) 1885 #error 1886 #endif 1887 int main(void) { return 0; }''') 1888 if not have_netmap and get_option('netmap').enabled() 1889 error('Netmap headers not available') 1890 endif 1891endif 1892config_host_data.set('CONFIG_NETMAP', have_netmap) 1893 1894# Work around a system header bug with some kernel/XFS header 1895# versions where they both try to define 'struct fsxattr': 1896# xfs headers will not try to redefine structs from linux headers 1897# if this macro is set. 1898config_host_data.set('HAVE_FSXATTR', cc.links(''' 1899 #include <linux/fs.h> 1900 struct fsxattr foo; 1901 int main(void) { 1902 return 0; 1903 }''')) 1904 1905# Some versions of Mac OS X incorrectly define SIZE_MAX 1906config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 1907 #include <stdint.h> 1908 #include <stdio.h> 1909 int main(int argc, char *argv[]) { 1910 return printf("%zu", SIZE_MAX); 1911 }''', args: ['-Werror'])) 1912 1913atomic_test = ''' 1914 #include <stdint.h> 1915 int main(void) 1916 { 1917 @0@ x = 0, y = 0; 1918 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 1919 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 1920 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 1921 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 1922 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 1923 return 0; 1924 }''' 1925 1926# See if 64-bit atomic operations are supported. 1927# Note that without __atomic builtins, we can only 1928# assume atomic loads/stores max at pointer size. 1929config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t'))) 1930 1931has_int128 = cc.links(''' 1932 __int128_t a; 1933 __uint128_t b; 1934 int main (void) { 1935 a = a + b; 1936 b = a * b; 1937 a = a * a; 1938 return 0; 1939 }''') 1940 1941config_host_data.set('CONFIG_INT128', has_int128) 1942 1943if has_int128 1944 # "do we have 128-bit atomics which are handled inline and specifically not 1945 # via libatomic". The reason we can't use libatomic is documented in the 1946 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 1947 has_atomic128 = cc.links(atomic_test.format('unsigned __int128')) 1948 1949 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 1950 1951 if not has_atomic128 1952 has_cmpxchg128 = cc.links(''' 1953 int main(void) 1954 { 1955 unsigned __int128 x = 0, y = 0; 1956 __sync_val_compare_and_swap_16(&x, y, x); 1957 return 0; 1958 } 1959 ''') 1960 1961 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128) 1962 endif 1963endif 1964 1965config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 1966 #include <sys/auxv.h> 1967 int main(void) { 1968 return getauxval(AT_HWCAP) == 0; 1969 }''')) 1970 1971config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 1972 #include <linux/usbdevice_fs.h> 1973 1974 #ifndef USBDEVFS_GET_CAPABILITIES 1975 #error "USBDEVFS_GET_CAPABILITIES undefined" 1976 #endif 1977 1978 #ifndef USBDEVFS_DISCONNECT_CLAIM 1979 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 1980 #endif 1981 1982 int main(void) { return 0; }''')) 1983 1984have_keyring = get_option('keyring') \ 1985 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \ 1986 .require(cc.compiles(''' 1987 #include <errno.h> 1988 #include <asm/unistd.h> 1989 #include <linux/keyctl.h> 1990 #include <sys/syscall.h> 1991 #include <unistd.h> 1992 int main(void) { 1993 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 1994 }'''), error_message: 'keyctl syscall not available on this system').allowed() 1995config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 1996 1997have_cpuid_h = cc.links(''' 1998 #include <cpuid.h> 1999 int main(void) { 2000 unsigned a, b, c, d; 2001 unsigned max = __get_cpuid_max(0, 0); 2002 2003 if (max >= 1) { 2004 __cpuid(1, a, b, c, d); 2005 } 2006 2007 if (max >= 7) { 2008 __cpuid_count(7, 0, a, b, c, d); 2009 } 2010 2011 return 0; 2012 }''') 2013config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 2014 2015config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 2016 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 2017 .require(cc.links(''' 2018 #pragma GCC push_options 2019 #pragma GCC target("avx2") 2020 #include <cpuid.h> 2021 #include <immintrin.h> 2022 static int bar(void *a) { 2023 __m256i x = *(__m256i *)a; 2024 return _mm256_testz_si256(x, x); 2025 } 2026 int main(int argc, char *argv[]) { return bar(argv[0]); } 2027 '''), error_message: 'AVX2 not available').allowed()) 2028 2029config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ 2030 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \ 2031 .require(cc.links(''' 2032 #pragma GCC push_options 2033 #pragma GCC target("avx512f") 2034 #include <cpuid.h> 2035 #include <immintrin.h> 2036 static int bar(void *a) { 2037 __m512i x = *(__m512i *)a; 2038 return _mm512_test_epi64_mask(x, x); 2039 } 2040 int main(int argc, char *argv[]) { return bar(argv[0]); } 2041 '''), error_message: 'AVX512F not available').allowed()) 2042 2043have_pvrdma = get_option('pvrdma') \ 2044 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \ 2045 .require(cc.compiles(''' 2046 int main(void) 2047 { 2048 char buf = 0; 2049 void *addr = &buf; 2050 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED); 2051 2052 return 0; 2053 }'''), error_message: 'PVRDMA requires mremap').allowed() 2054 2055if have_pvrdma 2056 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.compiles(''' 2057 #include <infiniband/verbs.h> 2058 int main(void) 2059 { 2060 struct ibv_mr *mr; 2061 struct ibv_pd *pd = NULL; 2062 size_t length = 10; 2063 uint64_t iova = 0; 2064 int access = 0; 2065 void *addr = NULL; 2066 2067 mr = ibv_reg_mr_iova(pd, addr, length, iova, access); 2068 ibv_dereg_mr(mr); 2069 return 0; 2070 }''')) 2071endif 2072 2073if get_option('membarrier').disabled() 2074 have_membarrier = false 2075elif targetos == 'windows' 2076 have_membarrier = true 2077elif targetos == 'linux' 2078 have_membarrier = cc.compiles(''' 2079 #include <linux/membarrier.h> 2080 #include <sys/syscall.h> 2081 #include <unistd.h> 2082 #include <stdlib.h> 2083 int main(void) { 2084 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 2085 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 2086 exit(0); 2087 }''') 2088endif 2089config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 2090 .require(have_membarrier, error_message: 'membarrier system call not available') \ 2091 .allowed()) 2092 2093have_afalg = get_option('crypto_afalg') \ 2094 .require(cc.compiles(gnu_source_prefix + ''' 2095 #include <errno.h> 2096 #include <sys/types.h> 2097 #include <sys/socket.h> 2098 #include <linux/if_alg.h> 2099 int main(void) { 2100 int sock; 2101 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 2102 return sock; 2103 } 2104 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 2105config_host_data.set('CONFIG_AF_ALG', have_afalg) 2106 2107config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 2108 'linux/vm_sockets.h', 'AF_VSOCK', 2109 prefix: '#include <sys/socket.h>', 2110)) 2111 2112have_vss = false 2113have_vss_sdk = false # old xp/2003 SDK 2114if targetos == 'windows' and link_language == 'cpp' 2115 have_vss = cxx.compiles(''' 2116 #define __MIDL_user_allocate_free_DEFINED__ 2117 #include <vss.h> 2118 int main(void) { return VSS_CTX_BACKUP; }''') 2119 have_vss_sdk = cxx.has_header('vscoordint.h') 2120endif 2121config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 2122 2123ignored = ['CONFIG_QEMU_INTERP_PREFIX', # actually per-target 2124 'HAVE_GDB_BIN'] 2125arrays = ['CONFIG_BDRV_RW_WHITELIST', 'CONFIG_BDRV_RO_WHITELIST'] 2126foreach k, v: config_host 2127 if ignored.contains(k) 2128 # do nothing 2129 elif arrays.contains(k) 2130 if v != '' 2131 v = '"' + '", "'.join(v.split()) + '", ' 2132 endif 2133 config_host_data.set(k, v) 2134 elif k.startswith('CONFIG_') 2135 config_host_data.set(k, v == 'y' ? 1 : v) 2136 endif 2137endforeach 2138 2139# Older versions of MinGW do not import _lock_file and _unlock_file properly. 2140# This was fixed for v6.0.0 with commit b48e3ac8969d. 2141if targetos == 'windows' 2142 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 2143 #include <stdio.h> 2144 int main(void) { 2145 _lock_file(NULL); 2146 _unlock_file(NULL); 2147 return 0; 2148 }''', name: '_lock_file and _unlock_file')) 2149endif 2150 2151######################## 2152# Target configuration # 2153######################## 2154 2155minikconf = find_program('scripts/minikconf.py') 2156config_all = {} 2157config_all_devices = {} 2158config_all_disas = {} 2159config_devices_mak_list = [] 2160config_devices_h = {} 2161config_target_h = {} 2162config_target_mak = {} 2163 2164disassemblers = { 2165 'alpha' : ['CONFIG_ALPHA_DIS'], 2166 'arm' : ['CONFIG_ARM_DIS'], 2167 'avr' : ['CONFIG_AVR_DIS'], 2168 'cris' : ['CONFIG_CRIS_DIS'], 2169 'hexagon' : ['CONFIG_HEXAGON_DIS'], 2170 'hppa' : ['CONFIG_HPPA_DIS'], 2171 'i386' : ['CONFIG_I386_DIS'], 2172 'x86_64' : ['CONFIG_I386_DIS'], 2173 'm68k' : ['CONFIG_M68K_DIS'], 2174 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 2175 'mips' : ['CONFIG_MIPS_DIS'], 2176 'nios2' : ['CONFIG_NIOS2_DIS'], 2177 'or1k' : ['CONFIG_OPENRISC_DIS'], 2178 'ppc' : ['CONFIG_PPC_DIS'], 2179 'riscv' : ['CONFIG_RISCV_DIS'], 2180 'rx' : ['CONFIG_RX_DIS'], 2181 's390' : ['CONFIG_S390_DIS'], 2182 'sh4' : ['CONFIG_SH4_DIS'], 2183 'sparc' : ['CONFIG_SPARC_DIS'], 2184 'xtensa' : ['CONFIG_XTENSA_DIS'], 2185} 2186if link_language == 'cpp' 2187 disassemblers += { 2188 'aarch64' : [ 'CONFIG_ARM_A64_DIS'], 2189 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'], 2190 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'], 2191 } 2192endif 2193 2194have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 2195host_kconfig = \ 2196 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 2197 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 2198 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 2199 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 2200 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 2201 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 2202 ('CONFIG_VHOST_USER' in config_host ? ['CONFIG_VHOST_USER=y'] : []) + \ 2203 ('CONFIG_VHOST_VDPA' in config_host ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 2204 ('CONFIG_VHOST_KERNEL' in config_host ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 2205 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 2206 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ 2207 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \ 2208 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) 2209 2210ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 2211 2212default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 2213actual_target_dirs = [] 2214fdt_required = [] 2215foreach target : target_dirs 2216 config_target = { 'TARGET_NAME': target.split('-')[0] } 2217 if target.endswith('linux-user') 2218 if targetos != 'linux' 2219 if default_targets 2220 continue 2221 endif 2222 error('Target @0@ is only available on a Linux host'.format(target)) 2223 endif 2224 config_target += { 'CONFIG_LINUX_USER': 'y' } 2225 elif target.endswith('bsd-user') 2226 if 'CONFIG_BSD' not in config_host 2227 if default_targets 2228 continue 2229 endif 2230 error('Target @0@ is only available on a BSD host'.format(target)) 2231 endif 2232 config_target += { 'CONFIG_BSD_USER': 'y' } 2233 elif target.endswith('softmmu') 2234 config_target += { 'CONFIG_SOFTMMU': 'y' } 2235 endif 2236 if target.endswith('-user') 2237 config_target += { 2238 'CONFIG_USER_ONLY': 'y', 2239 'CONFIG_QEMU_INTERP_PREFIX': 2240 config_host['CONFIG_QEMU_INTERP_PREFIX'].format(config_target['TARGET_NAME']) 2241 } 2242 endif 2243 2244 accel_kconfig = [] 2245 foreach sym: accelerators 2246 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 2247 config_target += { sym: 'y' } 2248 config_all += { sym: 'y' } 2249 if sym == 'CONFIG_TCG' and tcg_arch == 'tci' 2250 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' } 2251 endif 2252 if target in modular_tcg 2253 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 2254 else 2255 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 2256 endif 2257 accel_kconfig += [ sym + '=y' ] 2258 endif 2259 endforeach 2260 if accel_kconfig.length() == 0 2261 if default_targets 2262 continue 2263 endif 2264 error('No accelerator available for target @0@'.format(target)) 2265 endif 2266 2267 actual_target_dirs += target 2268 config_target += keyval.load('configs/targets' / target + '.mak') 2269 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 2270 2271 if 'TARGET_NEED_FDT' in config_target 2272 fdt_required += target 2273 endif 2274 2275 # Add default keys 2276 if 'TARGET_BASE_ARCH' not in config_target 2277 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 2278 endif 2279 if 'TARGET_ABI_DIR' not in config_target 2280 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 2281 endif 2282 if 'TARGET_BIG_ENDIAN' not in config_target 2283 config_target += {'TARGET_BIG_ENDIAN': 'n'} 2284 endif 2285 2286 foreach k, v: disassemblers 2287 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 2288 foreach sym: v 2289 config_target += { sym: 'y' } 2290 config_all_disas += { sym: 'y' } 2291 endforeach 2292 endif 2293 endforeach 2294 2295 config_target_data = configuration_data() 2296 foreach k, v: config_target 2297 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 2298 # do nothing 2299 elif ignored.contains(k) 2300 # do nothing 2301 elif k == 'TARGET_BASE_ARCH' 2302 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 2303 # not used to select files from sourcesets. 2304 config_target_data.set('TARGET_' + v.to_upper(), 1) 2305 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 2306 config_target_data.set_quoted(k, v) 2307 elif v == 'y' 2308 config_target_data.set(k, 1) 2309 elif v == 'n' 2310 config_target_data.set(k, 0) 2311 else 2312 config_target_data.set(k, v) 2313 endif 2314 endforeach 2315 config_target_data.set('QEMU_ARCH', 2316 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 2317 config_target_h += {target: configure_file(output: target + '-config-target.h', 2318 configuration: config_target_data)} 2319 2320 if target.endswith('-softmmu') 2321 config_input = meson.get_external_property(target, 'default') 2322 config_devices_mak = target + '-config-devices.mak' 2323 config_devices_mak = configure_file( 2324 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 2325 output: config_devices_mak, 2326 depfile: config_devices_mak + '.d', 2327 capture: true, 2328 command: [minikconf, 2329 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 2330 config_devices_mak, '@DEPFILE@', '@INPUT@', 2331 host_kconfig, accel_kconfig, 2332 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y']) 2333 2334 config_devices_data = configuration_data() 2335 config_devices = keyval.load(config_devices_mak) 2336 foreach k, v: config_devices 2337 config_devices_data.set(k, 1) 2338 endforeach 2339 config_devices_mak_list += config_devices_mak 2340 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 2341 configuration: config_devices_data)} 2342 config_target += config_devices 2343 config_all_devices += config_devices 2344 endif 2345 config_target_mak += {target: config_target} 2346endforeach 2347target_dirs = actual_target_dirs 2348 2349# This configuration is used to build files that are shared by 2350# multiple binaries, and then extracted out of the "common" 2351# static_library target. 2352# 2353# We do not use all_sources()/all_dependencies(), because it would 2354# build literally all source files, including devices only used by 2355# targets that are not built for this compilation. The CONFIG_ALL 2356# pseudo symbol replaces it. 2357 2358config_all += config_all_devices 2359config_all += config_host 2360config_all += config_all_disas 2361config_all += { 2362 'CONFIG_XEN': config_host.has_key('CONFIG_XEN_BACKEND'), 2363 'CONFIG_SOFTMMU': have_system, 2364 'CONFIG_USER_ONLY': have_user, 2365 'CONFIG_ALL': true, 2366} 2367 2368target_configs_h = [] 2369foreach target: target_dirs 2370 target_configs_h += config_target_h[target] 2371 target_configs_h += config_devices_h.get(target, []) 2372endforeach 2373genh += custom_target('config-poison.h', 2374 input: [target_configs_h], 2375 output: 'config-poison.h', 2376 capture: true, 2377 command: [find_program('scripts/make-config-poison.sh'), 2378 target_configs_h]) 2379 2380############## 2381# Submodules # 2382############## 2383 2384capstone = not_found 2385capstone_opt = get_option('capstone') 2386if capstone_opt in ['enabled', 'auto', 'system'] 2387 have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile') 2388 capstone = dependency('capstone', version: '>=4.0', 2389 kwargs: static_kwargs, method: 'pkg-config', 2390 required: capstone_opt == 'system' or 2391 capstone_opt == 'enabled' and not have_internal) 2392 2393 # Some versions of capstone have broken pkg-config file 2394 # that reports a wrong -I path, causing the #include to 2395 # fail later. If the system has such a broken version 2396 # do not use it. 2397 if capstone.found() and not cc.compiles('#include <capstone.h>', 2398 dependencies: [capstone]) 2399 capstone = not_found 2400 if capstone_opt == 'system' 2401 error('system capstone requested, it does not appear to work') 2402 endif 2403 endif 2404 2405 if capstone.found() 2406 capstone_opt = 'system' 2407 elif have_internal 2408 capstone_opt = 'internal' 2409 else 2410 capstone_opt = 'disabled' 2411 endif 2412endif 2413if capstone_opt == 'internal' 2414 capstone_data = configuration_data() 2415 capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1') 2416 2417 capstone_files = files( 2418 'capstone/cs.c', 2419 'capstone/MCInst.c', 2420 'capstone/MCInstrDesc.c', 2421 'capstone/MCRegisterInfo.c', 2422 'capstone/SStream.c', 2423 'capstone/utils.c' 2424 ) 2425 2426 if 'CONFIG_ARM_DIS' in config_all_disas 2427 capstone_data.set('CAPSTONE_HAS_ARM', '1') 2428 capstone_files += files( 2429 'capstone/arch/ARM/ARMDisassembler.c', 2430 'capstone/arch/ARM/ARMInstPrinter.c', 2431 'capstone/arch/ARM/ARMMapping.c', 2432 'capstone/arch/ARM/ARMModule.c' 2433 ) 2434 endif 2435 2436 # FIXME: This config entry currently depends on a c++ compiler. 2437 # Which is needed for building libvixl, but not for capstone. 2438 if 'CONFIG_ARM_A64_DIS' in config_all_disas 2439 capstone_data.set('CAPSTONE_HAS_ARM64', '1') 2440 capstone_files += files( 2441 'capstone/arch/AArch64/AArch64BaseInfo.c', 2442 'capstone/arch/AArch64/AArch64Disassembler.c', 2443 'capstone/arch/AArch64/AArch64InstPrinter.c', 2444 'capstone/arch/AArch64/AArch64Mapping.c', 2445 'capstone/arch/AArch64/AArch64Module.c' 2446 ) 2447 endif 2448 2449 if 'CONFIG_PPC_DIS' in config_all_disas 2450 capstone_data.set('CAPSTONE_HAS_POWERPC', '1') 2451 capstone_files += files( 2452 'capstone/arch/PowerPC/PPCDisassembler.c', 2453 'capstone/arch/PowerPC/PPCInstPrinter.c', 2454 'capstone/arch/PowerPC/PPCMapping.c', 2455 'capstone/arch/PowerPC/PPCModule.c' 2456 ) 2457 endif 2458 2459 if 'CONFIG_S390_DIS' in config_all_disas 2460 capstone_data.set('CAPSTONE_HAS_SYSZ', '1') 2461 capstone_files += files( 2462 'capstone/arch/SystemZ/SystemZDisassembler.c', 2463 'capstone/arch/SystemZ/SystemZInstPrinter.c', 2464 'capstone/arch/SystemZ/SystemZMapping.c', 2465 'capstone/arch/SystemZ/SystemZModule.c', 2466 'capstone/arch/SystemZ/SystemZMCTargetDesc.c' 2467 ) 2468 endif 2469 2470 if 'CONFIG_I386_DIS' in config_all_disas 2471 capstone_data.set('CAPSTONE_HAS_X86', 1) 2472 capstone_files += files( 2473 'capstone/arch/X86/X86Disassembler.c', 2474 'capstone/arch/X86/X86DisassemblerDecoder.c', 2475 'capstone/arch/X86/X86ATTInstPrinter.c', 2476 'capstone/arch/X86/X86IntelInstPrinter.c', 2477 'capstone/arch/X86/X86InstPrinterCommon.c', 2478 'capstone/arch/X86/X86Mapping.c', 2479 'capstone/arch/X86/X86Module.c' 2480 ) 2481 endif 2482 2483 configure_file(output: 'capstone-defs.h', configuration: capstone_data) 2484 2485 capstone_cargs = [ 2486 # FIXME: There does not seem to be a way to completely replace the c_args 2487 # that come from add_project_arguments() -- we can only add to them. 2488 # So: disable all warnings with a big hammer. 2489 '-Wno-error', '-w', 2490 2491 # Include all configuration defines via a header file, which will wind up 2492 # as a dependency on the object file, and thus changes here will result 2493 # in a rebuild. 2494 '-include', 'capstone-defs.h' 2495 ] 2496 2497 libcapstone = static_library('capstone', 2498 build_by_default: false, 2499 sources: capstone_files, 2500 c_args: capstone_cargs, 2501 include_directories: 'capstone/include') 2502 capstone = declare_dependency(link_with: libcapstone, 2503 include_directories: 'capstone/include/capstone') 2504endif 2505 2506slirp = not_found 2507slirp_opt = 'disabled' 2508if have_system 2509 slirp_opt = get_option('slirp') 2510 if slirp_opt in ['enabled', 'auto', 'system'] 2511 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') 2512 slirp = dependency('slirp', kwargs: static_kwargs, 2513 method: 'pkg-config', 2514 required: slirp_opt == 'system' or 2515 slirp_opt == 'enabled' and not have_internal) 2516 if slirp.found() 2517 slirp_opt = 'system' 2518 elif have_internal 2519 slirp_opt = 'internal' 2520 else 2521 slirp_opt = 'disabled' 2522 endif 2523 endif 2524 if slirp_opt == 'internal' 2525 slirp_deps = [] 2526 if targetos == 'windows' 2527 slirp_deps = cc.find_library('iphlpapi') 2528 elif targetos == 'darwin' 2529 slirp_deps = cc.find_library('resolv') 2530 endif 2531 slirp_conf = configuration_data() 2532 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) 2533 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1]) 2534 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2]) 2535 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version()) 2536 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"'] 2537 slirp_files = [ 2538 'slirp/src/arp_table.c', 2539 'slirp/src/bootp.c', 2540 'slirp/src/cksum.c', 2541 'slirp/src/dhcpv6.c', 2542 'slirp/src/dnssearch.c', 2543 'slirp/src/if.c', 2544 'slirp/src/ip6_icmp.c', 2545 'slirp/src/ip6_input.c', 2546 'slirp/src/ip6_output.c', 2547 'slirp/src/ip_icmp.c', 2548 'slirp/src/ip_input.c', 2549 'slirp/src/ip_output.c', 2550 'slirp/src/mbuf.c', 2551 'slirp/src/misc.c', 2552 'slirp/src/ncsi.c', 2553 'slirp/src/ndp_table.c', 2554 'slirp/src/sbuf.c', 2555 'slirp/src/slirp.c', 2556 'slirp/src/socket.c', 2557 'slirp/src/state.c', 2558 'slirp/src/stream.c', 2559 'slirp/src/tcp_input.c', 2560 'slirp/src/tcp_output.c', 2561 'slirp/src/tcp_subr.c', 2562 'slirp/src/tcp_timer.c', 2563 'slirp/src/tftp.c', 2564 'slirp/src/udp.c', 2565 'slirp/src/udp6.c', 2566 'slirp/src/util.c', 2567 'slirp/src/version.c', 2568 'slirp/src/vmstate.c', 2569 ] 2570 2571 configure_file( 2572 input : 'slirp/src/libslirp-version.h.in', 2573 output : 'libslirp-version.h', 2574 configuration: slirp_conf) 2575 2576 slirp_inc = include_directories('slirp', 'slirp/src') 2577 libslirp = static_library('slirp', 2578 build_by_default: false, 2579 sources: slirp_files, 2580 c_args: slirp_cargs, 2581 include_directories: slirp_inc) 2582 slirp = declare_dependency(link_with: libslirp, 2583 dependencies: slirp_deps, 2584 include_directories: slirp_inc) 2585 endif 2586endif 2587 2588# For CFI, we need to compile slirp as a static library together with qemu. 2589# This is because we register slirp functions as callbacks for QEMU Timers. 2590# When using a system-wide shared libslirp, the type information for the 2591# callback is missing and the timer call produces a false positive with CFI. 2592# 2593# Now that slirp_opt has been defined, check if the selected slirp is compatible 2594# with control-flow integrity. 2595if get_option('cfi') and slirp_opt == 'system' 2596 error('Control-Flow Integrity is not compatible with system-wide slirp.' \ 2597 + ' Please configure with --enable-slirp=git') 2598endif 2599 2600fdt = not_found 2601if have_system 2602 fdt_opt = get_option('fdt') 2603 if fdt_opt in ['enabled', 'auto', 'system'] 2604 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') 2605 fdt = cc.find_library('fdt', kwargs: static_kwargs, 2606 required: fdt_opt == 'system' or 2607 fdt_opt == 'enabled' and not have_internal) 2608 if fdt.found() and cc.links(''' 2609 #include <libfdt.h> 2610 #include <libfdt_env.h> 2611 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''', 2612 dependencies: fdt) 2613 fdt_opt = 'system' 2614 elif fdt_opt == 'system' 2615 error('system libfdt requested, but it is too old (1.5.1 or newer required)') 2616 elif have_internal 2617 fdt_opt = 'internal' 2618 else 2619 fdt_opt = 'disabled' 2620 fdt = not_found 2621 endif 2622 endif 2623 if fdt_opt == 'internal' 2624 fdt_files = files( 2625 'dtc/libfdt/fdt.c', 2626 'dtc/libfdt/fdt_ro.c', 2627 'dtc/libfdt/fdt_wip.c', 2628 'dtc/libfdt/fdt_sw.c', 2629 'dtc/libfdt/fdt_rw.c', 2630 'dtc/libfdt/fdt_strerror.c', 2631 'dtc/libfdt/fdt_empty_tree.c', 2632 'dtc/libfdt/fdt_addresses.c', 2633 'dtc/libfdt/fdt_overlay.c', 2634 'dtc/libfdt/fdt_check.c', 2635 ) 2636 2637 fdt_inc = include_directories('dtc/libfdt') 2638 libfdt = static_library('fdt', 2639 build_by_default: false, 2640 sources: fdt_files, 2641 include_directories: fdt_inc) 2642 fdt = declare_dependency(link_with: libfdt, 2643 include_directories: fdt_inc) 2644 endif 2645else 2646 fdt_opt = 'disabled' 2647endif 2648if not fdt.found() and fdt_required.length() > 0 2649 error('fdt not available but required by targets ' + ', '.join(fdt_required)) 2650endif 2651 2652config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2653config_host_data.set('CONFIG_FDT', fdt.found()) 2654config_host_data.set('CONFIG_SLIRP', slirp.found()) 2655 2656##################### 2657# Generated sources # 2658##################### 2659 2660genh += configure_file(output: 'config-host.h', configuration: config_host_data) 2661 2662hxtool = find_program('scripts/hxtool') 2663shaderinclude = find_program('scripts/shaderinclude.pl') 2664qapi_gen = find_program('scripts/qapi-gen.py') 2665qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 2666 meson.current_source_dir() / 'scripts/qapi/commands.py', 2667 meson.current_source_dir() / 'scripts/qapi/common.py', 2668 meson.current_source_dir() / 'scripts/qapi/error.py', 2669 meson.current_source_dir() / 'scripts/qapi/events.py', 2670 meson.current_source_dir() / 'scripts/qapi/expr.py', 2671 meson.current_source_dir() / 'scripts/qapi/gen.py', 2672 meson.current_source_dir() / 'scripts/qapi/introspect.py', 2673 meson.current_source_dir() / 'scripts/qapi/parser.py', 2674 meson.current_source_dir() / 'scripts/qapi/schema.py', 2675 meson.current_source_dir() / 'scripts/qapi/source.py', 2676 meson.current_source_dir() / 'scripts/qapi/types.py', 2677 meson.current_source_dir() / 'scripts/qapi/visit.py', 2678 meson.current_source_dir() / 'scripts/qapi/common.py', 2679 meson.current_source_dir() / 'scripts/qapi-gen.py' 2680] 2681 2682tracetool = [ 2683 python, files('scripts/tracetool.py'), 2684 '--backend=' + ','.join(get_option('trace_backends')) 2685] 2686tracetool_depends = files( 2687 'scripts/tracetool/backend/log.py', 2688 'scripts/tracetool/backend/__init__.py', 2689 'scripts/tracetool/backend/dtrace.py', 2690 'scripts/tracetool/backend/ftrace.py', 2691 'scripts/tracetool/backend/simple.py', 2692 'scripts/tracetool/backend/syslog.py', 2693 'scripts/tracetool/backend/ust.py', 2694 'scripts/tracetool/format/ust_events_c.py', 2695 'scripts/tracetool/format/ust_events_h.py', 2696 'scripts/tracetool/format/__init__.py', 2697 'scripts/tracetool/format/d.py', 2698 'scripts/tracetool/format/simpletrace_stap.py', 2699 'scripts/tracetool/format/c.py', 2700 'scripts/tracetool/format/h.py', 2701 'scripts/tracetool/format/log_stap.py', 2702 'scripts/tracetool/format/stap.py', 2703 'scripts/tracetool/__init__.py', 2704 'scripts/tracetool/transform.py', 2705 'scripts/tracetool/vcpu.py' 2706) 2707 2708qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 2709 meson.current_source_dir(), 2710 config_host['PKGVERSION'], meson.project_version()] 2711qemu_version = custom_target('qemu-version.h', 2712 output: 'qemu-version.h', 2713 command: qemu_version_cmd, 2714 capture: true, 2715 build_by_default: true, 2716 build_always_stale: true) 2717genh += qemu_version 2718 2719hxdep = [] 2720hx_headers = [ 2721 ['qemu-options.hx', 'qemu-options.def'], 2722 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 2723] 2724if have_system 2725 hx_headers += [ 2726 ['hmp-commands.hx', 'hmp-commands.h'], 2727 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 2728 ] 2729endif 2730foreach d : hx_headers 2731 hxdep += custom_target(d[1], 2732 input: files(d[0]), 2733 output: d[1], 2734 capture: true, 2735 build_by_default: true, # to be removed when added to a target 2736 command: [hxtool, '-h', '@INPUT0@']) 2737endforeach 2738genh += hxdep 2739 2740################### 2741# Collect sources # 2742################### 2743 2744authz_ss = ss.source_set() 2745blockdev_ss = ss.source_set() 2746block_ss = ss.source_set() 2747chardev_ss = ss.source_set() 2748common_ss = ss.source_set() 2749crypto_ss = ss.source_set() 2750hwcore_ss = ss.source_set() 2751io_ss = ss.source_set() 2752qmp_ss = ss.source_set() 2753qom_ss = ss.source_set() 2754softmmu_ss = ss.source_set() 2755specific_fuzz_ss = ss.source_set() 2756specific_ss = ss.source_set() 2757stub_ss = ss.source_set() 2758trace_ss = ss.source_set() 2759user_ss = ss.source_set() 2760util_ss = ss.source_set() 2761 2762# accel modules 2763qtest_module_ss = ss.source_set() 2764tcg_module_ss = ss.source_set() 2765 2766modules = {} 2767target_modules = {} 2768hw_arch = {} 2769target_arch = {} 2770target_softmmu_arch = {} 2771target_user_arch = {} 2772 2773############### 2774# Trace files # 2775############### 2776 2777# TODO: add each directory to the subdirs from its own meson.build, once 2778# we have those 2779trace_events_subdirs = [ 2780 'crypto', 2781 'qapi', 2782 'qom', 2783 'monitor', 2784 'util', 2785] 2786if have_linux_user 2787 trace_events_subdirs += [ 'linux-user' ] 2788endif 2789if have_bsd_user 2790 trace_events_subdirs += [ 'bsd-user' ] 2791endif 2792if have_block 2793 trace_events_subdirs += [ 2794 'authz', 2795 'block', 2796 'io', 2797 'nbd', 2798 'scsi', 2799 ] 2800endif 2801if have_system 2802 trace_events_subdirs += [ 2803 'accel/kvm', 2804 'audio', 2805 'backends', 2806 'backends/tpm', 2807 'chardev', 2808 'ebpf', 2809 'hw/9pfs', 2810 'hw/acpi', 2811 'hw/adc', 2812 'hw/alpha', 2813 'hw/arm', 2814 'hw/audio', 2815 'hw/block', 2816 'hw/block/dataplane', 2817 'hw/char', 2818 'hw/display', 2819 'hw/dma', 2820 'hw/hppa', 2821 'hw/hyperv', 2822 'hw/i2c', 2823 'hw/i386', 2824 'hw/i386/xen', 2825 'hw/ide', 2826 'hw/input', 2827 'hw/intc', 2828 'hw/isa', 2829 'hw/mem', 2830 'hw/mips', 2831 'hw/misc', 2832 'hw/misc/macio', 2833 'hw/net', 2834 'hw/net/can', 2835 'hw/nubus', 2836 'hw/nvme', 2837 'hw/nvram', 2838 'hw/pci', 2839 'hw/pci-host', 2840 'hw/ppc', 2841 'hw/rdma', 2842 'hw/rdma/vmw', 2843 'hw/rtc', 2844 'hw/s390x', 2845 'hw/scsi', 2846 'hw/sd', 2847 'hw/sh4', 2848 'hw/sparc', 2849 'hw/sparc64', 2850 'hw/ssi', 2851 'hw/timer', 2852 'hw/tpm', 2853 'hw/usb', 2854 'hw/vfio', 2855 'hw/virtio', 2856 'hw/watchdog', 2857 'hw/xen', 2858 'hw/gpio', 2859 'migration', 2860 'net', 2861 'softmmu', 2862 'ui', 2863 'hw/remote', 2864 ] 2865endif 2866if have_system or have_user 2867 trace_events_subdirs += [ 2868 'accel/tcg', 2869 'hw/core', 2870 'target/arm', 2871 'target/arm/hvf', 2872 'target/hppa', 2873 'target/i386', 2874 'target/i386/kvm', 2875 'target/mips/tcg', 2876 'target/nios2', 2877 'target/ppc', 2878 'target/riscv', 2879 'target/s390x', 2880 'target/s390x/kvm', 2881 'target/sparc', 2882 ] 2883endif 2884 2885vhost_user = not_found 2886if targetos == 'linux' and 'CONFIG_VHOST_USER' in config_host 2887 libvhost_user = subproject('libvhost-user') 2888 vhost_user = libvhost_user.get_variable('vhost_user_dep') 2889endif 2890 2891# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 2892# that is filled in by qapi/. 2893subdir('qapi') 2894subdir('qobject') 2895subdir('stubs') 2896subdir('trace') 2897subdir('util') 2898subdir('qom') 2899subdir('authz') 2900subdir('crypto') 2901subdir('ui') 2902 2903 2904if enable_modules 2905 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 2906 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 2907endif 2908 2909stub_ss = stub_ss.apply(config_all, strict: false) 2910 2911util_ss.add_all(trace_ss) 2912util_ss = util_ss.apply(config_all, strict: false) 2913libqemuutil = static_library('qemuutil', 2914 sources: util_ss.sources() + stub_ss.sources() + genh, 2915 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman]) 2916qemuutil = declare_dependency(link_with: libqemuutil, 2917 sources: genh + version_res) 2918 2919if have_system or have_user 2920 decodetree = generator(find_program('scripts/decodetree.py'), 2921 output: 'decode-@BASENAME@.c.inc', 2922 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 2923 subdir('libdecnumber') 2924 subdir('target') 2925endif 2926 2927subdir('audio') 2928subdir('io') 2929subdir('chardev') 2930subdir('fsdev') 2931subdir('dump') 2932 2933if have_block 2934 block_ss.add(files( 2935 'block.c', 2936 'blockjob.c', 2937 'job.c', 2938 'qemu-io-cmds.c', 2939 )) 2940 if config_host_data.get('CONFIG_REPLICATION') 2941 block_ss.add(files('replication.c')) 2942 endif 2943 2944 subdir('nbd') 2945 subdir('scsi') 2946 subdir('block') 2947 2948 blockdev_ss.add(files( 2949 'blockdev.c', 2950 'blockdev-nbd.c', 2951 'iothread.c', 2952 'job-qmp.c', 2953 ), gnutls) 2954 2955 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 2956 # os-win32.c does not 2957 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 2958 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 2959endif 2960 2961common_ss.add(files('cpus-common.c')) 2962 2963subdir('softmmu') 2964 2965common_ss.add(capstone) 2966specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone) 2967 2968# Work around a gcc bug/misfeature wherein constant propagation looks 2969# through an alias: 2970# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 2971# to guess that a const variable is always zero. Without lto, this is 2972# impossible, as the alias is restricted to page-vary-common.c. Indeed, 2973# without lto, not even the alias is required -- we simply use different 2974# declarations in different compilation units. 2975pagevary = files('page-vary-common.c') 2976if get_option('b_lto') 2977 pagevary_flags = ['-fno-lto'] 2978 if get_option('cfi') 2979 pagevary_flags += '-fno-sanitize=cfi-icall' 2980 endif 2981 pagevary = static_library('page-vary-common', sources: pagevary + genh, 2982 c_args: pagevary_flags) 2983 pagevary = declare_dependency(link_with: pagevary) 2984endif 2985common_ss.add(pagevary) 2986specific_ss.add(files('page-vary.c')) 2987 2988subdir('backends') 2989subdir('disas') 2990subdir('migration') 2991subdir('monitor') 2992subdir('net') 2993subdir('replay') 2994subdir('semihosting') 2995subdir('hw') 2996subdir('tcg') 2997subdir('fpu') 2998subdir('accel') 2999subdir('plugins') 3000subdir('ebpf') 3001 3002common_user_inc = [] 3003 3004subdir('common-user') 3005subdir('bsd-user') 3006subdir('linux-user') 3007 3008# needed for fuzzing binaries 3009subdir('tests/qtest/libqos') 3010subdir('tests/qtest/fuzz') 3011 3012# accel modules 3013tcg_real_module_ss = ss.source_set() 3014tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3015specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3016target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3017 'tcg': tcg_real_module_ss }} 3018 3019######################## 3020# Library dependencies # 3021######################## 3022 3023modinfo_collect = find_program('scripts/modinfo-collect.py') 3024modinfo_generate = find_program('scripts/modinfo-generate.py') 3025modinfo_files = [] 3026 3027block_mods = [] 3028softmmu_mods = [] 3029foreach d, list : modules 3030 foreach m, module_ss : list 3031 if enable_modules and targetos != 'windows' 3032 module_ss = module_ss.apply(config_all, strict: false) 3033 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3034 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 3035 if d == 'block' 3036 block_mods += sl 3037 else 3038 softmmu_mods += sl 3039 endif 3040 if module_ss.sources() != [] 3041 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3042 # input. Sources can be used multiple times but objects are 3043 # unique when it comes to lookup in compile_commands.json. 3044 # Depnds on a mesion version with 3045 # https://github.com/mesonbuild/meson/pull/8900 3046 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3047 output: d + '-' + m + '.modinfo', 3048 input: module_ss.sources() + genh, 3049 capture: true, 3050 command: [modinfo_collect, module_ss.sources()]) 3051 endif 3052 else 3053 if d == 'block' 3054 block_ss.add_all(module_ss) 3055 else 3056 softmmu_ss.add_all(module_ss) 3057 endif 3058 endif 3059 endforeach 3060endforeach 3061 3062foreach d, list : target_modules 3063 foreach m, module_ss : list 3064 if enable_modules and targetos != 'windows' 3065 foreach target : target_dirs 3066 if target.endswith('-softmmu') 3067 config_target = config_target_mak[target] 3068 config_target += config_host 3069 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3070 c_args = ['-DNEED_CPU_H', 3071 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3072 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3073 target_module_ss = module_ss.apply(config_target, strict: false) 3074 if target_module_ss.sources() != [] 3075 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3076 sl = static_library(module_name, 3077 [genh, target_module_ss.sources()], 3078 dependencies: [modulecommon, target_module_ss.dependencies()], 3079 include_directories: target_inc, 3080 c_args: c_args, 3081 pic: true) 3082 softmmu_mods += sl 3083 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3084 modinfo_files += custom_target(module_name + '.modinfo', 3085 output: module_name + '.modinfo', 3086 input: target_module_ss.sources() + genh, 3087 capture: true, 3088 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3089 endif 3090 endif 3091 endforeach 3092 else 3093 specific_ss.add_all(module_ss) 3094 endif 3095 endforeach 3096endforeach 3097 3098if enable_modules 3099 modinfo_src = custom_target('modinfo.c', 3100 output: 'modinfo.c', 3101 input: modinfo_files, 3102 command: [modinfo_generate, '@INPUT@'], 3103 capture: true) 3104 modinfo_lib = static_library('modinfo', modinfo_src) 3105 modinfo_dep = declare_dependency(link_whole: modinfo_lib) 3106 softmmu_ss.add(modinfo_dep) 3107endif 3108 3109nm = find_program('nm') 3110undefsym = find_program('scripts/undefsym.py') 3111block_syms = custom_target('block.syms', output: 'block.syms', 3112 input: [libqemuutil, block_mods], 3113 capture: true, 3114 command: [undefsym, nm, '@INPUT@']) 3115qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3116 input: [libqemuutil, softmmu_mods], 3117 capture: true, 3118 command: [undefsym, nm, '@INPUT@']) 3119 3120qom_ss = qom_ss.apply(config_host, strict: false) 3121libqom = static_library('qom', qom_ss.sources() + genh, 3122 dependencies: [qom_ss.dependencies()], 3123 name_suffix: 'fa') 3124 3125qom = declare_dependency(link_whole: libqom) 3126 3127authz_ss = authz_ss.apply(config_host, strict: false) 3128libauthz = static_library('authz', authz_ss.sources() + genh, 3129 dependencies: [authz_ss.dependencies()], 3130 name_suffix: 'fa', 3131 build_by_default: false) 3132 3133authz = declare_dependency(link_whole: libauthz, 3134 dependencies: qom) 3135 3136crypto_ss = crypto_ss.apply(config_host, strict: false) 3137libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3138 dependencies: [crypto_ss.dependencies()], 3139 name_suffix: 'fa', 3140 build_by_default: false) 3141 3142crypto = declare_dependency(link_whole: libcrypto, 3143 dependencies: [authz, qom]) 3144 3145io_ss = io_ss.apply(config_host, strict: false) 3146libio = static_library('io', io_ss.sources() + genh, 3147 dependencies: [io_ss.dependencies()], 3148 link_with: libqemuutil, 3149 name_suffix: 'fa', 3150 build_by_default: false) 3151 3152io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 3153 3154libmigration = static_library('migration', sources: migration_files + genh, 3155 name_suffix: 'fa', 3156 build_by_default: false) 3157migration = declare_dependency(link_with: libmigration, 3158 dependencies: [zlib, qom, io]) 3159softmmu_ss.add(migration) 3160 3161block_ss = block_ss.apply(config_host, strict: false) 3162libblock = static_library('block', block_ss.sources() + genh, 3163 dependencies: block_ss.dependencies(), 3164 link_depends: block_syms, 3165 name_suffix: 'fa', 3166 build_by_default: false) 3167 3168block = declare_dependency(link_whole: [libblock], 3169 link_args: '@block.syms', 3170 dependencies: [crypto, io]) 3171 3172blockdev_ss = blockdev_ss.apply(config_host, strict: false) 3173libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3174 dependencies: blockdev_ss.dependencies(), 3175 name_suffix: 'fa', 3176 build_by_default: false) 3177 3178blockdev = declare_dependency(link_whole: [libblockdev], 3179 dependencies: [block]) 3180 3181qmp_ss = qmp_ss.apply(config_host, strict: false) 3182libqmp = static_library('qmp', qmp_ss.sources() + genh, 3183 dependencies: qmp_ss.dependencies(), 3184 name_suffix: 'fa', 3185 build_by_default: false) 3186 3187qmp = declare_dependency(link_whole: [libqmp]) 3188 3189libchardev = static_library('chardev', chardev_ss.sources() + genh, 3190 name_suffix: 'fa', 3191 dependencies: chardev_ss.dependencies(), 3192 build_by_default: false) 3193 3194chardev = declare_dependency(link_whole: libchardev) 3195 3196hwcore_ss = hwcore_ss.apply(config_host, strict: false) 3197libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3198 name_suffix: 'fa', 3199 build_by_default: false) 3200hwcore = declare_dependency(link_whole: libhwcore) 3201common_ss.add(hwcore) 3202 3203########### 3204# Targets # 3205########### 3206 3207emulator_modules = [] 3208foreach m : block_mods + softmmu_mods 3209 emulator_modules += shared_module(m.name(), 3210 build_by_default: true, 3211 name_prefix: '', 3212 link_whole: m, 3213 install: true, 3214 install_dir: qemu_moddir) 3215endforeach 3216 3217softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3218common_ss.add(qom, qemuutil) 3219 3220common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 3221common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3222 3223common_all = common_ss.apply(config_all, strict: false) 3224common_all = static_library('common', 3225 build_by_default: false, 3226 sources: common_all.sources() + genh, 3227 include_directories: common_user_inc, 3228 implicit_include_directories: false, 3229 dependencies: common_all.dependencies(), 3230 name_suffix: 'fa') 3231 3232feature_to_c = find_program('scripts/feature_to_c.sh') 3233 3234if targetos == 'darwin' 3235 entitlement = find_program('scripts/entitlement.sh') 3236endif 3237 3238emulators = {} 3239foreach target : target_dirs 3240 config_target = config_target_mak[target] 3241 target_name = config_target['TARGET_NAME'] 3242 target_base_arch = config_target['TARGET_BASE_ARCH'] 3243 arch_srcs = [config_target_h[target]] 3244 arch_deps = [] 3245 c_args = ['-DNEED_CPU_H', 3246 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3247 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3248 link_args = emulator_link_args 3249 3250 config_target += config_host 3251 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3252 if targetos == 'linux' 3253 target_inc += include_directories('linux-headers', is_system: true) 3254 endif 3255 if target.endswith('-softmmu') 3256 qemu_target_name = 'qemu-system-' + target_name 3257 target_type='system' 3258 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false) 3259 arch_srcs += t.sources() 3260 arch_deps += t.dependencies() 3261 3262 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3263 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3264 arch_srcs += hw.sources() 3265 arch_deps += hw.dependencies() 3266 3267 arch_srcs += config_devices_h[target] 3268 link_args += ['@block.syms', '@qemu.syms'] 3269 else 3270 abi = config_target['TARGET_ABI_DIR'] 3271 target_type='user' 3272 target_inc += common_user_inc 3273 qemu_target_name = 'qemu-' + target_name 3274 if target_base_arch in target_user_arch 3275 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3276 arch_srcs += t.sources() 3277 arch_deps += t.dependencies() 3278 endif 3279 if 'CONFIG_LINUX_USER' in config_target 3280 base_dir = 'linux-user' 3281 endif 3282 if 'CONFIG_BSD_USER' in config_target 3283 base_dir = 'bsd-user' 3284 target_inc += include_directories('bsd-user/' / targetos) 3285 target_inc += include_directories('bsd-user/host/' / host_arch) 3286 dir = base_dir / abi 3287 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3288 endif 3289 target_inc += include_directories( 3290 base_dir, 3291 base_dir / abi, 3292 ) 3293 if 'CONFIG_LINUX_USER' in config_target 3294 dir = base_dir / abi 3295 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3296 if config_target.has_key('TARGET_SYSTBL_ABI') 3297 arch_srcs += \ 3298 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3299 extra_args : config_target['TARGET_SYSTBL_ABI']) 3300 endif 3301 endif 3302 endif 3303 3304 if 'TARGET_XML_FILES' in config_target 3305 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3306 output: target + '-gdbstub-xml.c', 3307 input: files(config_target['TARGET_XML_FILES'].split()), 3308 command: [feature_to_c, '@INPUT@'], 3309 capture: true) 3310 arch_srcs += gdbstub_xml 3311 endif 3312 3313 t = target_arch[target_base_arch].apply(config_target, strict: false) 3314 arch_srcs += t.sources() 3315 arch_deps += t.dependencies() 3316 3317 target_common = common_ss.apply(config_target, strict: false) 3318 objects = common_all.extract_objects(target_common.sources()) 3319 deps = target_common.dependencies() 3320 3321 target_specific = specific_ss.apply(config_target, strict: false) 3322 arch_srcs += target_specific.sources() 3323 arch_deps += target_specific.dependencies() 3324 3325 lib = static_library('qemu-' + target, 3326 sources: arch_srcs + genh, 3327 dependencies: arch_deps, 3328 objects: objects, 3329 include_directories: target_inc, 3330 c_args: c_args, 3331 build_by_default: false, 3332 name_suffix: 'fa') 3333 3334 if target.endswith('-softmmu') 3335 execs = [{ 3336 'name': 'qemu-system-' + target_name, 3337 'win_subsystem': 'console', 3338 'sources': files('softmmu/main.c'), 3339 'dependencies': [] 3340 }] 3341 if targetos == 'windows' and (sdl.found() or gtk.found()) 3342 execs += [{ 3343 'name': 'qemu-system-' + target_name + 'w', 3344 'win_subsystem': 'windows', 3345 'sources': files('softmmu/main.c'), 3346 'dependencies': [] 3347 }] 3348 endif 3349 if get_option('fuzzing') 3350 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 3351 execs += [{ 3352 'name': 'qemu-fuzz-' + target_name, 3353 'win_subsystem': 'console', 3354 'sources': specific_fuzz.sources(), 3355 'dependencies': specific_fuzz.dependencies(), 3356 }] 3357 endif 3358 else 3359 execs = [{ 3360 'name': 'qemu-' + target_name, 3361 'win_subsystem': 'console', 3362 'sources': [], 3363 'dependencies': [] 3364 }] 3365 endif 3366 foreach exe: execs 3367 exe_name = exe['name'] 3368 if targetos == 'darwin' 3369 exe_name += '-unsigned' 3370 endif 3371 3372 emulator = executable(exe_name, exe['sources'], 3373 install: true, 3374 c_args: c_args, 3375 dependencies: arch_deps + deps + exe['dependencies'], 3376 objects: lib.extract_all_objects(recursive: true), 3377 link_language: link_language, 3378 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 3379 link_args: link_args, 3380 win_subsystem: exe['win_subsystem']) 3381 3382 if targetos == 'darwin' 3383 icon = 'pc-bios/qemu.rsrc' 3384 build_input = [emulator, files(icon)] 3385 install_input = [ 3386 get_option('bindir') / exe_name, 3387 meson.current_source_dir() / icon 3388 ] 3389 if 'CONFIG_HVF' in config_target 3390 entitlements = 'accel/hvf/entitlements.plist' 3391 build_input += files(entitlements) 3392 install_input += meson.current_source_dir() / entitlements 3393 endif 3394 3395 emulators += {exe['name'] : custom_target(exe['name'], 3396 input: build_input, 3397 output: exe['name'], 3398 command: [entitlement, '@OUTPUT@', '@INPUT@']) 3399 } 3400 3401 meson.add_install_script(entitlement, '--install', 3402 get_option('bindir') / exe['name'], 3403 install_input) 3404 else 3405 emulators += {exe['name']: emulator} 3406 endif 3407 3408 if stap.found() 3409 foreach stp: [ 3410 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 3411 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 3412 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 3413 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 3414 ] 3415 custom_target(exe['name'] + stp['ext'], 3416 input: trace_events_all, 3417 output: exe['name'] + stp['ext'], 3418 install: stp['install'], 3419 install_dir: get_option('datadir') / 'systemtap/tapset', 3420 command: [ 3421 tracetool, '--group=all', '--format=' + stp['fmt'], 3422 '--binary=' + stp['bin'], 3423 '--target-name=' + target_name, 3424 '--target-type=' + target_type, 3425 '--probe-prefix=qemu.' + target_type + '.' + target_name, 3426 '@INPUT@', '@OUTPUT@' 3427 ], 3428 depend_files: tracetool_depends) 3429 endforeach 3430 endif 3431 endforeach 3432endforeach 3433 3434# Other build targets 3435 3436if 'CONFIG_PLUGIN' in config_host 3437 install_headers('include/qemu/qemu-plugin.h') 3438endif 3439 3440subdir('qga') 3441 3442# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3443# when we don't build tools or system 3444if xkbcommon.found() 3445 # used for the update-keymaps target, so include rules even if !have_tools 3446 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 3447 dependencies: [qemuutil, xkbcommon], install: have_tools) 3448endif 3449 3450if have_tools 3451 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 3452 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 3453 qemu_io = executable('qemu-io', files('qemu-io.c'), 3454 dependencies: [block, qemuutil], install: true) 3455 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 3456 dependencies: [blockdev, qemuutil, gnutls, selinux], 3457 install: true) 3458 3459 subdir('storage-daemon') 3460 subdir('contrib/rdmacm-mux') 3461 subdir('contrib/elf2dmp') 3462 3463 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 3464 dependencies: qemuutil, 3465 install: true) 3466 3467 if 'CONFIG_VHOST_USER' in config_host 3468 subdir('contrib/vhost-user-blk') 3469 subdir('contrib/vhost-user-gpu') 3470 subdir('contrib/vhost-user-input') 3471 subdir('contrib/vhost-user-scsi') 3472 endif 3473 3474 if targetos == 'linux' 3475 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 3476 dependencies: [qemuutil, libcap_ng], 3477 install: true, 3478 install_dir: get_option('libexecdir')) 3479 3480 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 3481 dependencies: [authz, crypto, io, qom, qemuutil, 3482 libcap_ng, mpathpersist], 3483 install: true) 3484 endif 3485 3486 if have_ivshmem 3487 subdir('contrib/ivshmem-client') 3488 subdir('contrib/ivshmem-server') 3489 endif 3490endif 3491 3492subdir('scripts') 3493subdir('tools') 3494subdir('pc-bios') 3495subdir('docs') 3496subdir('tests') 3497if gtk.found() 3498 subdir('po') 3499endif 3500 3501if host_machine.system() == 'windows' 3502 nsis_cmd = [ 3503 find_program('scripts/nsis.py'), 3504 '@OUTPUT@', 3505 get_option('prefix'), 3506 meson.current_source_dir(), 3507 host_machine.cpu(), 3508 '--', 3509 '-DDISPLAYVERSION=' + meson.project_version(), 3510 ] 3511 if build_docs 3512 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 3513 endif 3514 if gtk.found() 3515 nsis_cmd += '-DCONFIG_GTK=y' 3516 endif 3517 3518 nsis = custom_target('nsis', 3519 output: 'qemu-setup-' + meson.project_version() + '.exe', 3520 input: files('qemu.nsi'), 3521 build_always_stale: true, 3522 command: nsis_cmd + ['@INPUT@']) 3523 alias_target('installer', nsis) 3524endif 3525 3526######################### 3527# Configuration summary # 3528######################### 3529 3530# Directories 3531summary_info = {} 3532summary_info += {'Install prefix': get_option('prefix')} 3533summary_info += {'BIOS directory': qemu_datadir} 3534summary_info += {'firmware path': get_option('qemu_firmwarepath')} 3535summary_info += {'binary directory': get_option('bindir')} 3536summary_info += {'library directory': get_option('libdir')} 3537summary_info += {'module directory': qemu_moddir} 3538summary_info += {'libexec directory': get_option('libexecdir')} 3539summary_info += {'include directory': get_option('includedir')} 3540summary_info += {'config directory': get_option('sysconfdir')} 3541if targetos != 'windows' 3542 summary_info += {'local state directory': get_option('localstatedir')} 3543 summary_info += {'Manual directory': get_option('mandir')} 3544else 3545 summary_info += {'local state directory': 'queried at runtime'} 3546endif 3547summary_info += {'Doc directory': get_option('docdir')} 3548summary_info += {'Build directory': meson.current_build_dir()} 3549summary_info += {'Source path': meson.current_source_dir()} 3550summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 3551summary(summary_info, bool_yn: true, section: 'Directories') 3552 3553# Host binaries 3554summary_info = {} 3555summary_info += {'git': config_host['GIT']} 3556summary_info += {'make': config_host['MAKE']} 3557summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 3558summary_info += {'sphinx-build': sphinx_build} 3559if config_host.has_key('HAVE_GDB_BIN') 3560 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 3561endif 3562if get_option('iasl') != '' 3563 summary_info += {'iasl': get_option('iasl')} 3564else 3565 summary_info += {'iasl': false} 3566endif 3567summary_info += {'genisoimage': config_host['GENISOIMAGE']} 3568if targetos == 'windows' and have_ga 3569 summary_info += {'wixl': wixl} 3570endif 3571if slirp_opt != 'disabled' and have_system 3572 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 3573endif 3574summary(summary_info, bool_yn: true, section: 'Host binaries') 3575 3576# Configurable features 3577summary_info = {} 3578summary_info += {'Documentation': build_docs} 3579summary_info += {'system-mode emulation': have_system} 3580summary_info += {'user-mode emulation': have_user} 3581summary_info += {'block layer': have_block} 3582summary_info += {'Install blobs': get_option('install_blobs')} 3583summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} 3584if config_host.has_key('CONFIG_MODULES') 3585 summary_info += {'alternative module path': get_option('module_upgrades')} 3586endif 3587summary_info += {'fuzzing support': get_option('fuzzing')} 3588if have_system 3589 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 3590endif 3591summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 3592if 'simple' in get_option('trace_backends') 3593 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 3594endif 3595summary_info += {'D-Bus display': dbus_display} 3596summary_info += {'QOM debugging': get_option('qom_cast_debug')} 3597summary_info += {'vhost-kernel support': config_host.has_key('CONFIG_VHOST_KERNEL')} 3598summary_info += {'vhost-net support': config_host.has_key('CONFIG_VHOST_NET')} 3599summary_info += {'vhost-crypto support': config_host.has_key('CONFIG_VHOST_CRYPTO')} 3600summary_info += {'vhost-scsi support': config_host.has_key('CONFIG_VHOST_SCSI')} 3601summary_info += {'vhost-vsock support': config_host.has_key('CONFIG_VHOST_VSOCK')} 3602summary_info += {'vhost-user support': config_host.has_key('CONFIG_VHOST_USER')} 3603summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 3604summary_info += {'vhost-user-fs support': config_host.has_key('CONFIG_VHOST_USER_FS')} 3605summary_info += {'vhost-vdpa support': config_host.has_key('CONFIG_VHOST_VDPA')} 3606summary_info += {'build guest agent': have_ga} 3607summary(summary_info, bool_yn: true, section: 'Configurable features') 3608 3609# Compilation information 3610summary_info = {} 3611summary_info += {'host CPU': cpu} 3612summary_info += {'host endianness': build_machine.endian()} 3613summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 3614summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 3615if link_language == 'cpp' 3616 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 3617else 3618 summary_info += {'C++ compiler': false} 3619endif 3620if targetos == 'darwin' 3621 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 3622endif 3623summary_info += {'CFLAGS': ' '.join(get_option('c_args') 3624 + ['-O' + get_option('optimization')] 3625 + (get_option('debug') ? ['-g'] : []))} 3626if link_language == 'cpp' 3627 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') 3628 + ['-O' + get_option('optimization')] 3629 + (get_option('debug') ? ['-g'] : []))} 3630endif 3631if targetos == 'darwin' 3632 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') 3633 + ['-O' + get_option('optimization')] 3634 + (get_option('debug') ? ['-g'] : []))} 3635endif 3636link_args = get_option(link_language + '_link_args') 3637if link_args.length() > 0 3638 summary_info += {'LDFLAGS': ' '.join(link_args)} 3639endif 3640summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)} 3641summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)} 3642summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)} 3643summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 3644summary_info += {'profiler': get_option('profiler')} 3645summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 3646summary_info += {'PIE': get_option('b_pie')} 3647summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 3648summary_info += {'malloc trim support': has_malloc_trim} 3649summary_info += {'membarrier': have_membarrier} 3650summary_info += {'debug stack usage': get_option('debug_stack_usage')} 3651summary_info += {'mutex debugging': get_option('debug_mutex')} 3652summary_info += {'memory allocator': get_option('malloc')} 3653summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 3654summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 3655summary_info += {'gprof enabled': get_option('gprof')} 3656summary_info += {'gcov': get_option('b_coverage')} 3657summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} 3658summary_info += {'CFI support': get_option('cfi')} 3659if get_option('cfi') 3660 summary_info += {'CFI debug support': get_option('cfi_debug')} 3661endif 3662summary_info += {'strip binaries': get_option('strip')} 3663summary_info += {'sparse': sparse} 3664summary_info += {'mingw32 support': targetos == 'windows'} 3665 3666# snarf the cross-compilation information for tests 3667foreach target: target_dirs 3668 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak' 3669 if fs.exists(tcg_mak) 3670 config_cross_tcg = keyval.load(tcg_mak) 3671 target = config_cross_tcg['TARGET_NAME'] 3672 compiler = '' 3673 if 'DOCKER_CROSS_CC_GUEST' in config_cross_tcg 3674 summary_info += {target + ' tests': config_cross_tcg['DOCKER_CROSS_CC_GUEST'] + 3675 ' via ' + config_cross_tcg['DOCKER_IMAGE']} 3676 elif 'CROSS_CC_GUEST' in config_cross_tcg 3677 summary_info += {target + ' tests' 3678 : config_cross_tcg['CROSS_CC_GUEST'] } 3679 endif 3680 endif 3681endforeach 3682 3683summary(summary_info, bool_yn: true, section: 'Compilation') 3684 3685# Targets and accelerators 3686summary_info = {} 3687if have_system 3688 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 3689 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 3690 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 3691 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 3692 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')} 3693 summary_info += {'Xen support': config_host.has_key('CONFIG_XEN_BACKEND')} 3694 if config_host.has_key('CONFIG_XEN_BACKEND') 3695 summary_info += {'xen ctrl version': config_host['CONFIG_XEN_CTRL_INTERFACE_VERSION']} 3696 endif 3697endif 3698summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 3699if config_all.has_key('CONFIG_TCG') 3700 if get_option('tcg_interpreter') 3701 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 3702 else 3703 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 3704 endif 3705 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')} 3706 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 3707endif 3708summary_info += {'target list': ' '.join(target_dirs)} 3709if have_system 3710 summary_info += {'default devices': get_option('default_devices')} 3711 summary_info += {'out of process emulation': multiprocess_allowed} 3712endif 3713summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 3714 3715# Block layer 3716summary_info = {} 3717summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} 3718summary_info += {'coroutine pool': have_coroutine_pool} 3719if have_block 3720 summary_info += {'Block whitelist (rw)': config_host['CONFIG_BDRV_RW_WHITELIST']} 3721 summary_info += {'Block whitelist (ro)': config_host['CONFIG_BDRV_RO_WHITELIST']} 3722 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 3723 summary_info += {'VirtFS support': have_virtfs} 3724 summary_info += {'build virtiofs daemon': have_virtiofsd} 3725 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')} 3726 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 3727 summary_info += {'bochs support': get_option('bochs').allowed()} 3728 summary_info += {'cloop support': get_option('cloop').allowed()} 3729 summary_info += {'dmg support': get_option('dmg').allowed()} 3730 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 3731 summary_info += {'vdi support': get_option('vdi').allowed()} 3732 summary_info += {'vvfat support': get_option('vvfat').allowed()} 3733 summary_info += {'qed support': get_option('qed').allowed()} 3734 summary_info += {'parallels support': get_option('parallels').allowed()} 3735 summary_info += {'FUSE exports': fuse} 3736endif 3737summary(summary_info, bool_yn: true, section: 'Block layer support') 3738 3739# Crypto 3740summary_info = {} 3741summary_info += {'TLS priority': config_host['CONFIG_TLS_PRIORITY']} 3742summary_info += {'GNUTLS support': gnutls} 3743if gnutls.found() 3744 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 3745endif 3746summary_info += {'libgcrypt': gcrypt} 3747summary_info += {'nettle': nettle} 3748if nettle.found() 3749 summary_info += {' XTS': xts != 'private'} 3750endif 3751summary_info += {'AF_ALG support': have_afalg} 3752summary_info += {'rng-none': get_option('rng_none')} 3753summary_info += {'Linux keyring': have_keyring} 3754summary(summary_info, bool_yn: true, section: 'Crypto') 3755 3756# Libraries 3757summary_info = {} 3758if targetos == 'darwin' 3759 summary_info += {'Cocoa support': cocoa} 3760endif 3761summary_info += {'SDL support': sdl} 3762summary_info += {'SDL image support': sdl_image} 3763summary_info += {'GTK support': gtk} 3764summary_info += {'pixman': pixman} 3765summary_info += {'VTE support': vte} 3766summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp} 3767summary_info += {'libtasn1': tasn1} 3768summary_info += {'PAM': pam} 3769summary_info += {'iconv support': iconv} 3770summary_info += {'curses support': curses} 3771summary_info += {'virgl support': virgl} 3772summary_info += {'curl support': curl} 3773summary_info += {'Multipath support': mpathpersist} 3774summary_info += {'PNG support': png} 3775summary_info += {'VNC support': vnc} 3776if vnc.found() 3777 summary_info += {'VNC SASL support': sasl} 3778 summary_info += {'VNC JPEG support': jpeg} 3779endif 3780if targetos not in ['darwin', 'haiku', 'windows'] 3781 summary_info += {'OSS support': oss} 3782elif targetos == 'darwin' 3783 summary_info += {'CoreAudio support': coreaudio} 3784elif targetos == 'windows' 3785 summary_info += {'DirectSound support': dsound} 3786endif 3787if targetos == 'linux' 3788 summary_info += {'ALSA support': alsa} 3789 summary_info += {'PulseAudio support': pulse} 3790endif 3791summary_info += {'JACK support': jack} 3792summary_info += {'brlapi support': brlapi} 3793summary_info += {'vde support': vde} 3794summary_info += {'netmap support': have_netmap} 3795summary_info += {'l2tpv3 support': have_l2tpv3} 3796summary_info += {'Linux AIO support': libaio} 3797summary_info += {'Linux io_uring support': linux_io_uring} 3798summary_info += {'ATTR/XATTR support': libattr} 3799summary_info += {'RDMA support': rdma} 3800summary_info += {'PVRDMA support': have_pvrdma} 3801summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 3802summary_info += {'libcap-ng support': libcap_ng} 3803summary_info += {'bpf support': libbpf} 3804summary_info += {'spice protocol support': spice_protocol} 3805if spice_protocol.found() 3806 summary_info += {' spice server support': spice} 3807endif 3808summary_info += {'rbd support': rbd} 3809summary_info += {'smartcard support': cacard} 3810summary_info += {'U2F support': u2f} 3811summary_info += {'libusb': libusb} 3812summary_info += {'usb net redir': usbredir} 3813summary_info += {'OpenGL support (epoxy)': opengl} 3814summary_info += {'GBM': gbm} 3815summary_info += {'libiscsi support': libiscsi} 3816summary_info += {'libnfs support': libnfs} 3817if targetos == 'windows' 3818 if have_ga 3819 summary_info += {'QGA VSS support': have_qga_vss} 3820 endif 3821endif 3822summary_info += {'seccomp support': seccomp} 3823summary_info += {'GlusterFS support': glusterfs} 3824summary_info += {'TPM support': have_tpm} 3825summary_info += {'libssh support': libssh} 3826summary_info += {'lzo support': lzo} 3827summary_info += {'snappy support': snappy} 3828summary_info += {'bzip2 support': libbzip2} 3829summary_info += {'lzfse support': liblzfse} 3830summary_info += {'zstd support': zstd} 3831summary_info += {'NUMA host support': numa} 3832summary_info += {'capstone': capstone_opt == 'internal' ? capstone_opt : capstone} 3833summary_info += {'libpmem support': libpmem} 3834summary_info += {'libdaxctl support': libdaxctl} 3835summary_info += {'libudev': libudev} 3836# Dummy dependency, keep .found() 3837summary_info += {'FUSE lseek': fuse_lseek.found()} 3838summary_info += {'selinux': selinux} 3839summary(summary_info, bool_yn: true, section: 'Dependencies') 3840 3841if not supported_cpus.contains(cpu) 3842 message() 3843 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 3844 message() 3845 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 3846 message('The QEMU project intends to remove support for this host CPU in') 3847 message('a future release if nobody volunteers to maintain it and to') 3848 message('provide a build host for our continuous integration setup.') 3849 message('configure has succeeded and you can continue to build, but') 3850 message('if you care about QEMU on this platform you should contact') 3851 message('us upstream at qemu-devel@nongnu.org.') 3852endif 3853 3854if not supported_oses.contains(targetos) 3855 message() 3856 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 3857 message() 3858 message('Host OS ' + targetos + 'support is not currently maintained.') 3859 message('The QEMU project intends to remove support for this host OS in') 3860 message('a future release if nobody volunteers to maintain it and to') 3861 message('provide a build host for our continuous integration setup.') 3862 message('configure has succeeded and you can continue to build, but') 3863 message('if you care about QEMU on this platform you should contact') 3864 message('us upstream at qemu-devel@nongnu.org.') 3865endif 3866