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