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