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