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