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