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