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