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