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 1544# libbpf 1545libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config') 1546if libbpf.found() and not cc.links(''' 1547 #include <bpf/libbpf.h> 1548 int main(void) 1549 { 1550 bpf_object__destroy_skeleton(NULL); 1551 return 0; 1552 }''', dependencies: libbpf) 1553 libbpf = not_found 1554 if get_option('bpf').enabled() 1555 error('libbpf skeleton test failed') 1556 else 1557 warning('libbpf skeleton test failed, disabling') 1558 endif 1559endif 1560 1561################# 1562# config-host.h # 1563################# 1564 1565audio_drivers_selected = [] 1566if have_system 1567 audio_drivers_available = { 1568 'alsa': alsa.found(), 1569 'coreaudio': coreaudio.found(), 1570 'dsound': dsound.found(), 1571 'jack': jack.found(), 1572 'oss': oss.found(), 1573 'pa': pulse.found(), 1574 'sdl': sdl.found(), 1575 } 1576 foreach k, v: audio_drivers_available 1577 config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v) 1578 endforeach 1579 1580 # Default to native drivers first, OSS second, SDL third 1581 audio_drivers_priority = \ 1582 [ 'pa', 'coreaudio', 'dsound', 'oss' ] + \ 1583 (targetos == 'linux' ? [] : [ 'sdl' ]) 1584 audio_drivers_default = [] 1585 foreach k: audio_drivers_priority 1586 if audio_drivers_available[k] 1587 audio_drivers_default += k 1588 endif 1589 endforeach 1590 1591 foreach k: get_option('audio_drv_list') 1592 if k == 'default' 1593 audio_drivers_selected += audio_drivers_default 1594 elif not audio_drivers_available[k] 1595 error('Audio driver "@0@" not available.'.format(k)) 1596 else 1597 audio_drivers_selected += k 1598 endif 1599 endforeach 1600endif 1601config_host_data.set('CONFIG_AUDIO_DRIVERS', 1602 '"' + '", "'.join(audio_drivers_selected) + '", ') 1603 1604if get_option('cfi') 1605 cfi_flags=[] 1606 # Check for dependency on LTO 1607 if not get_option('b_lto') 1608 error('Selected Control-Flow Integrity but LTO is disabled') 1609 endif 1610 if config_host.has_key('CONFIG_MODULES') 1611 error('Selected Control-Flow Integrity is not compatible with modules') 1612 endif 1613 # Check for cfi flags. CFI requires LTO so we can't use 1614 # get_supported_arguments, but need a more complex "compiles" which allows 1615 # custom arguments 1616 if cc.compiles('int main () { return 0; }', name: '-fsanitize=cfi-icall', 1617 args: ['-flto', '-fsanitize=cfi-icall'] ) 1618 cfi_flags += '-fsanitize=cfi-icall' 1619 else 1620 error('-fsanitize=cfi-icall is not supported by the compiler') 1621 endif 1622 if cc.compiles('int main () { return 0; }', 1623 name: '-fsanitize-cfi-icall-generalize-pointers', 1624 args: ['-flto', '-fsanitize=cfi-icall', 1625 '-fsanitize-cfi-icall-generalize-pointers'] ) 1626 cfi_flags += '-fsanitize-cfi-icall-generalize-pointers' 1627 else 1628 error('-fsanitize-cfi-icall-generalize-pointers is not supported by the compiler') 1629 endif 1630 if get_option('cfi_debug') 1631 if cc.compiles('int main () { return 0; }', 1632 name: '-fno-sanitize-trap=cfi-icall', 1633 args: ['-flto', '-fsanitize=cfi-icall', 1634 '-fno-sanitize-trap=cfi-icall'] ) 1635 cfi_flags += '-fno-sanitize-trap=cfi-icall' 1636 else 1637 error('-fno-sanitize-trap=cfi-icall is not supported by the compiler') 1638 endif 1639 endif 1640 add_global_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) 1641 add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc']) 1642endif 1643 1644have_host_block_device = (targetos != 'darwin' or 1645 cc.has_header('IOKit/storage/IOMedia.h')) 1646 1647# FIXME enable_modules shouldn't be necessary, but: https://github.com/mesonbuild/meson/issues/8333 1648dbus_display = get_option('dbus_display') \ 1649 .require(gio.version().version_compare('>=2.64'), 1650 error_message: '-display dbus requires glib>=2.64') \ 1651 .require(enable_modules, 1652 error_message: '-display dbus requires --enable-modules') \ 1653 .require(gdbus_codegen.found(), 1654 error_message: '-display dbus requires gdbus-codegen') \ 1655 .allowed() 1656 1657have_virtfs = get_option('virtfs') \ 1658 .require(targetos == 'linux' or targetos == 'darwin', 1659 error_message: 'virtio-9p (virtfs) requires Linux or macOS') \ 1660 .require(targetos == 'linux' or cc.has_function('pthread_fchdir_np'), 1661 error_message: 'virtio-9p (virtfs) on macOS requires the presence of pthread_fchdir_np') \ 1662 .require(targetos == 'darwin' or (libattr.found() and libcap_ng.found()), 1663 error_message: 'virtio-9p (virtfs) on Linux requires libcap-ng-devel and libattr-devel') \ 1664 .disable_auto_if(not have_tools and not have_system) \ 1665 .allowed() 1666 1667have_virtfs_proxy_helper = targetos != 'darwin' and have_virtfs and have_tools 1668 1669if get_option('block_drv_ro_whitelist') == '' 1670 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', '') 1671else 1672 config_host_data.set('CONFIG_BDRV_RO_WHITELIST', 1673 '"' + get_option('block_drv_ro_whitelist').replace(',', '", "') + '", ') 1674endif 1675if get_option('block_drv_rw_whitelist') == '' 1676 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', '') 1677else 1678 config_host_data.set('CONFIG_BDRV_RW_WHITELIST', 1679 '"' + get_option('block_drv_rw_whitelist').replace(',', '", "') + '", ') 1680endif 1681 1682foreach k : get_option('trace_backends') 1683 config_host_data.set('CONFIG_TRACE_' + k.to_upper(), true) 1684endforeach 1685config_host_data.set_quoted('CONFIG_TRACE_FILE', get_option('trace_file')) 1686config_host_data.set_quoted('CONFIG_TLS_PRIORITY', get_option('tls_priority')) 1687if iasl.found() 1688 config_host_data.set_quoted('CONFIG_IASL', iasl.full_path()) 1689endif 1690config_host_data.set_quoted('CONFIG_BINDIR', get_option('prefix') / get_option('bindir')) 1691config_host_data.set_quoted('CONFIG_PREFIX', get_option('prefix')) 1692config_host_data.set_quoted('CONFIG_QEMU_CONFDIR', get_option('prefix') / qemu_confdir) 1693config_host_data.set_quoted('CONFIG_QEMU_DATADIR', get_option('prefix') / qemu_datadir) 1694config_host_data.set_quoted('CONFIG_QEMU_DESKTOPDIR', get_option('prefix') / qemu_desktopdir) 1695config_host_data.set_quoted('CONFIG_QEMU_FIRMWAREPATH', get_option('prefix') / get_option('qemu_firmwarepath')) 1696config_host_data.set_quoted('CONFIG_QEMU_HELPERDIR', get_option('prefix') / get_option('libexecdir')) 1697config_host_data.set_quoted('CONFIG_QEMU_ICONDIR', get_option('prefix') / qemu_icondir) 1698config_host_data.set_quoted('CONFIG_QEMU_LOCALEDIR', get_option('prefix') / get_option('localedir')) 1699config_host_data.set_quoted('CONFIG_QEMU_LOCALSTATEDIR', get_option('prefix') / get_option('localstatedir')) 1700config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / qemu_moddir) 1701config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) 1702 1703if config_host.has_key('CONFIG_MODULES') 1704 config_host_data.set('CONFIG_STAMP', run_command( 1705 meson.current_source_dir() / 'scripts/qemu-stamp.py', 1706 meson.project_version(), get_option('pkgversion'), '--', 1707 meson.current_source_dir() / 'configure', 1708 capture: true, check: true).stdout().strip()) 1709endif 1710 1711have_slirp_smbd = get_option('slirp_smbd') \ 1712 .require(targetos != 'windows', error_message: 'Host smbd not supported on this platform.') \ 1713 .allowed() 1714if have_slirp_smbd 1715 smbd_path = get_option('smbd') 1716 if smbd_path == '' 1717 smbd_path = (targetos == 'solaris' ? '/usr/sfw/sbin/smbd' : '/usr/sbin/smbd') 1718 endif 1719 config_host_data.set_quoted('CONFIG_SMBD_COMMAND', smbd_path) 1720endif 1721 1722config_host_data.set('HOST_' + host_arch.to_upper(), 1) 1723 1724if get_option('module_upgrades') and not enable_modules 1725 error('Cannot enable module-upgrades as modules are not enabled') 1726endif 1727config_host_data.set('CONFIG_MODULE_UPGRADES', get_option('module_upgrades')) 1728 1729config_host_data.set('CONFIG_ATTR', libattr.found()) 1730config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', get_option('block_drv_whitelist_in_tools')) 1731config_host_data.set('CONFIG_BRLAPI', brlapi.found()) 1732config_host_data.set('CONFIG_COCOA', cocoa.found()) 1733config_host_data.set('CONFIG_FUZZ', get_option('fuzzing')) 1734config_host_data.set('CONFIG_GCOV', get_option('b_coverage')) 1735config_host_data.set('CONFIG_LIBUDEV', libudev.found()) 1736config_host_data.set('CONFIG_LZO', lzo.found()) 1737config_host_data.set('CONFIG_MPATH', mpathpersist.found()) 1738config_host_data.set('CONFIG_MPATH_NEW_API', mpathpersist_new_api) 1739config_host_data.set('CONFIG_CURL', curl.found()) 1740config_host_data.set('CONFIG_CURSES', curses.found()) 1741config_host_data.set('CONFIG_GBM', gbm.found()) 1742config_host_data.set('CONFIG_GIO', gio.found()) 1743config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 1744if glusterfs.found() 1745 config_host_data.set('CONFIG_GLUSTERFS_XLATOR_OPT', glusterfs.version().version_compare('>=4')) 1746 config_host_data.set('CONFIG_GLUSTERFS_DISCARD', glusterfs.version().version_compare('>=5')) 1747 config_host_data.set('CONFIG_GLUSTERFS_FALLOCATE', glusterfs.version().version_compare('>=6')) 1748 config_host_data.set('CONFIG_GLUSTERFS_ZEROFILL', glusterfs.version().version_compare('>=6')) 1749 config_host_data.set('CONFIG_GLUSTERFS_FTRUNCATE_HAS_STAT', glusterfs_ftruncate_has_stat) 1750 config_host_data.set('CONFIG_GLUSTERFS_IOCB_HAS_STAT', glusterfs_iocb_has_stat) 1751endif 1752config_host_data.set('CONFIG_GTK', gtk.found()) 1753config_host_data.set('CONFIG_VTE', vte.found()) 1754config_host_data.set('CONFIG_LIBATTR', have_old_libattr) 1755config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found()) 1756config_host_data.set('CONFIG_EBPF', libbpf.found()) 1757config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found()) 1758config_host_data.set('CONFIG_LIBISCSI', libiscsi.found()) 1759config_host_data.set('CONFIG_LIBNFS', libnfs.found()) 1760config_host_data.set('CONFIG_LIBSSH', libssh.found()) 1761config_host_data.set('CONFIG_LINUX_AIO', libaio.found()) 1762config_host_data.set('CONFIG_LINUX_IO_URING', linux_io_uring.found()) 1763config_host_data.set('CONFIG_LIBURING_REGISTER_RING_FD', cc.has_function('io_uring_register_ring_fd', prefix: '#include <liburing.h>', dependencies:linux_io_uring)) 1764config_host_data.set('CONFIG_LIBPMEM', libpmem.found()) 1765config_host_data.set('CONFIG_NUMA', numa.found()) 1766config_host_data.set('CONFIG_OPENGL', opengl.found()) 1767config_host_data.set('CONFIG_PROFILER', get_option('profiler')) 1768config_host_data.set('CONFIG_RBD', rbd.found()) 1769config_host_data.set('CONFIG_RDMA', rdma.found()) 1770config_host_data.set('CONFIG_SDL', sdl.found()) 1771config_host_data.set('CONFIG_SDL_IMAGE', sdl_image.found()) 1772config_host_data.set('CONFIG_SECCOMP', seccomp.found()) 1773config_host_data.set('CONFIG_SNAPPY', snappy.found()) 1774config_host_data.set('CONFIG_TPM', have_tpm) 1775config_host_data.set('CONFIG_USB_LIBUSB', libusb.found()) 1776config_host_data.set('CONFIG_VDE', vde.found()) 1777config_host_data.set('CONFIG_VHOST_NET', have_vhost_net) 1778config_host_data.set('CONFIG_VHOST_NET_USER', have_vhost_net_user) 1779config_host_data.set('CONFIG_VHOST_NET_VDPA', have_vhost_net_vdpa) 1780config_host_data.set('CONFIG_VHOST_KERNEL', have_vhost_kernel) 1781config_host_data.set('CONFIG_VHOST_USER', have_vhost_user) 1782config_host_data.set('CONFIG_VHOST_CRYPTO', have_vhost_user_crypto) 1783config_host_data.set('CONFIG_VHOST_VDPA', have_vhost_vdpa) 1784config_host_data.set('CONFIG_VMNET', vmnet.found()) 1785config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server) 1786config_host_data.set('CONFIG_PNG', png.found()) 1787config_host_data.set('CONFIG_VNC', vnc.found()) 1788config_host_data.set('CONFIG_VNC_JPEG', jpeg.found()) 1789config_host_data.set('CONFIG_VNC_SASL', sasl.found()) 1790config_host_data.set('CONFIG_VIRTFS', have_virtfs) 1791config_host_data.set('CONFIG_VTE', vte.found()) 1792config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found()) 1793config_host_data.set('CONFIG_KEYUTILS', keyutils.found()) 1794config_host_data.set('CONFIG_GETTID', has_gettid) 1795config_host_data.set('CONFIG_GNUTLS', gnutls.found()) 1796config_host_data.set('CONFIG_GNUTLS_CRYPTO', gnutls_crypto.found()) 1797config_host_data.set('CONFIG_TASN1', tasn1.found()) 1798config_host_data.set('CONFIG_GCRYPT', gcrypt.found()) 1799config_host_data.set('CONFIG_NETTLE', nettle.found()) 1800config_host_data.set('CONFIG_HOGWEED', hogweed.found()) 1801config_host_data.set('CONFIG_QEMU_PRIVATE_XTS', xts == 'private') 1802config_host_data.set('CONFIG_MALLOC_TRIM', has_malloc_trim) 1803config_host_data.set('CONFIG_STATX', has_statx) 1804config_host_data.set('CONFIG_STATX_MNT_ID', has_statx_mnt_id) 1805config_host_data.set('CONFIG_ZSTD', zstd.found()) 1806config_host_data.set('CONFIG_FUSE', fuse.found()) 1807config_host_data.set('CONFIG_FUSE_LSEEK', fuse_lseek.found()) 1808config_host_data.set('CONFIG_SPICE_PROTOCOL', spice_protocol.found()) 1809if spice_protocol.found() 1810config_host_data.set('CONFIG_SPICE_PROTOCOL_MAJOR', spice_protocol.version().split('.')[0]) 1811config_host_data.set('CONFIG_SPICE_PROTOCOL_MINOR', spice_protocol.version().split('.')[1]) 1812config_host_data.set('CONFIG_SPICE_PROTOCOL_MICRO', spice_protocol.version().split('.')[2]) 1813endif 1814config_host_data.set('CONFIG_SPICE', spice.found()) 1815config_host_data.set('CONFIG_X11', x11.found()) 1816config_host_data.set('CONFIG_DBUS_DISPLAY', dbus_display) 1817config_host_data.set('CONFIG_CFI', get_option('cfi')) 1818config_host_data.set('CONFIG_SELINUX', selinux.found()) 1819config_host_data.set('CONFIG_XEN_BACKEND', xen.found()) 1820if xen.found() 1821 # protect from xen.version() having less than three components 1822 xen_version = xen.version().split('.') + ['0', '0'] 1823 xen_ctrl_version = xen_version[0] + \ 1824 ('0' + xen_version[1]).substring(-2) + \ 1825 ('0' + xen_version[2]).substring(-2) 1826 config_host_data.set('CONFIG_XEN_CTRL_INTERFACE_VERSION', xen_ctrl_version) 1827endif 1828config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version())) 1829config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0]) 1830config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1]) 1831config_host_data.set('QEMU_VERSION_MICRO', meson.project_version().split('.')[2]) 1832 1833config_host_data.set_quoted('CONFIG_HOST_DSOSUF', host_dsosuf) 1834config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device) 1835 1836have_coroutine_pool = get_option('coroutine_pool') 1837if get_option('debug_stack_usage') and have_coroutine_pool 1838 message('Disabling coroutine pool to measure stack usage') 1839 have_coroutine_pool = false 1840endif 1841config_host_data.set10('CONFIG_COROUTINE_POOL', have_coroutine_pool) 1842config_host_data.set('CONFIG_DEBUG_MUTEX', get_option('debug_mutex')) 1843config_host_data.set('CONFIG_DEBUG_STACK_USAGE', get_option('debug_stack_usage')) 1844config_host_data.set('CONFIG_GPROF', get_option('gprof')) 1845config_host_data.set('CONFIG_LIVE_BLOCK_MIGRATION', get_option('live_block_migration').allowed()) 1846config_host_data.set('CONFIG_QOM_CAST_DEBUG', get_option('qom_cast_debug')) 1847config_host_data.set('CONFIG_REPLICATION', get_option('live_block_migration').allowed()) 1848 1849# has_header 1850config_host_data.set('CONFIG_EPOLL', cc.has_header('sys/epoll.h')) 1851config_host_data.set('CONFIG_LINUX_MAGIC_H', cc.has_header('linux/magic.h')) 1852config_host_data.set('CONFIG_VALGRIND_H', cc.has_header('valgrind/valgrind.h')) 1853config_host_data.set('HAVE_BTRFS_H', cc.has_header('linux/btrfs.h')) 1854config_host_data.set('HAVE_DRM_H', cc.has_header('libdrm/drm.h')) 1855config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h')) 1856config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h')) 1857config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h')) 1858config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h')) 1859 1860# has_function 1861config_host_data.set('CONFIG_ACCEPT4', cc.has_function('accept4')) 1862config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime')) 1863config_host_data.set('CONFIG_DUP3', cc.has_function('dup3')) 1864config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate')) 1865config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate')) 1866# Note that we need to specify prefix: here to avoid incorrectly 1867# thinking that Windows has posix_memalign() 1868config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>')) 1869config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc')) 1870config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc')) 1871config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) 1872config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) 1873config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>')) 1874config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_fchdir_np')) 1875config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) 1876config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_function('unshare')) 1877config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) 1878config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) 1879config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) 1880config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) 1881config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) 1882config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) 1883config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) 1884config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>')) 1885if rdma.found() 1886 config_host_data.set('HAVE_IBV_ADVISE_MR', 1887 cc.has_function('ibv_advise_mr', 1888 dependencies: rdma, 1889 prefix: '#include <infiniband/verbs.h>')) 1890endif 1891 1892# has_header_symbol 1893config_host_data.set('CONFIG_BYTESWAP_H', 1894 cc.has_header_symbol('byteswap.h', 'bswap_32')) 1895config_host_data.set('CONFIG_EPOLL_CREATE1', 1896 cc.has_header_symbol('sys/epoll.h', 'epoll_create1')) 1897config_host_data.set('CONFIG_FALLOCATE_PUNCH_HOLE', 1898 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_PUNCH_HOLE') and 1899 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_KEEP_SIZE')) 1900config_host_data.set('CONFIG_FALLOCATE_ZERO_RANGE', 1901 cc.has_header_symbol('linux/falloc.h', 'FALLOC_FL_ZERO_RANGE')) 1902config_host_data.set('CONFIG_FIEMAP', 1903 cc.has_header('linux/fiemap.h') and 1904 cc.has_header_symbol('linux/fs.h', 'FS_IOC_FIEMAP')) 1905config_host_data.set('CONFIG_GETRANDOM', 1906 cc.has_function('getrandom') and 1907 cc.has_header_symbol('sys/random.h', 'GRND_NONBLOCK')) 1908config_host_data.set('CONFIG_INOTIFY', 1909 cc.has_header_symbol('sys/inotify.h', 'inotify_init')) 1910config_host_data.set('CONFIG_INOTIFY1', 1911 cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) 1912config_host_data.set('CONFIG_MACHINE_BSWAP_H', 1913 cc.has_header_symbol('machine/bswap.h', 'bswap32', 1914 prefix: '''#include <sys/endian.h> 1915 #include <sys/types.h>''')) 1916config_host_data.set('CONFIG_PRCTL_PR_SET_TIMERSLACK', 1917 cc.has_header_symbol('sys/prctl.h', 'PR_SET_TIMERSLACK')) 1918config_host_data.set('CONFIG_RTNETLINK', 1919 cc.has_header_symbol('linux/rtnetlink.h', 'IFLA_PROTO_DOWN')) 1920config_host_data.set('CONFIG_SYSMACROS', 1921 cc.has_header_symbol('sys/sysmacros.h', 'makedev')) 1922config_host_data.set('HAVE_OPTRESET', 1923 cc.has_header_symbol('getopt.h', 'optreset')) 1924config_host_data.set('HAVE_IPPROTO_MPTCP', 1925 cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) 1926 1927# has_member 1928config_host_data.set('HAVE_SIGEV_NOTIFY_THREAD_ID', 1929 cc.has_member('struct sigevent', 'sigev_notify_thread_id', 1930 prefix: '#include <signal.h>')) 1931config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM', 1932 cc.has_member('struct stat', 'st_atim', 1933 prefix: '#include <sys/stat.h>')) 1934 1935# has_type 1936config_host_data.set('CONFIG_IOVEC', 1937 cc.has_type('struct iovec', 1938 prefix: '#include <sys/uio.h>')) 1939config_host_data.set('HAVE_UTMPX', 1940 cc.has_type('struct utmpx', 1941 prefix: '#include <utmpx.h>')) 1942 1943config_host_data.set('CONFIG_EVENTFD', cc.links(''' 1944 #include <sys/eventfd.h> 1945 int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) 1946config_host_data.set('CONFIG_FDATASYNC', cc.links(gnu_source_prefix + ''' 1947 #include <unistd.h> 1948 int main(void) { 1949 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0 1950 return fdatasync(0); 1951 #else 1952 #error Not supported 1953 #endif 1954 }''')) 1955 1956has_madvise = cc.links(gnu_source_prefix + ''' 1957 #include <sys/types.h> 1958 #include <sys/mman.h> 1959 #include <stddef.h> 1960 int main(void) { return madvise(NULL, 0, MADV_DONTNEED); }''') 1961missing_madvise_proto = false 1962if has_madvise 1963 # Some platforms (illumos and Solaris before Solaris 11) provide madvise() 1964 # but forget to prototype it. In this case, has_madvise will be true (the 1965 # test program links despite a compile warning). To detect the 1966 # missing-prototype case, we try again with a definitely-bogus prototype. 1967 # This will only compile if the system headers don't provide the prototype; 1968 # otherwise the conflicting prototypes will cause a compiler error. 1969 missing_madvise_proto = cc.links(gnu_source_prefix + ''' 1970 #include <sys/types.h> 1971 #include <sys/mman.h> 1972 #include <stddef.h> 1973 extern int madvise(int); 1974 int main(void) { return madvise(0); }''') 1975endif 1976config_host_data.set('CONFIG_MADVISE', has_madvise) 1977config_host_data.set('HAVE_MADVISE_WITHOUT_PROTOTYPE', missing_madvise_proto) 1978 1979config_host_data.set('CONFIG_MEMFD', cc.links(gnu_source_prefix + ''' 1980 #include <sys/mman.h> 1981 int main(void) { return memfd_create("foo", MFD_ALLOW_SEALING); }''')) 1982config_host_data.set('CONFIG_OPEN_BY_HANDLE', cc.links(gnu_source_prefix + ''' 1983 #include <fcntl.h> 1984 #if !defined(AT_EMPTY_PATH) 1985 # error missing definition 1986 #else 1987 int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } 1988 #endif''')) 1989config_host_data.set('CONFIG_PIPE2', cc.links(gnu_source_prefix + ''' 1990 #include <unistd.h> 1991 #include <fcntl.h> 1992 1993 int main(void) 1994 { 1995 int pipefd[2]; 1996 return pipe2(pipefd, O_CLOEXEC); 1997 }''')) 1998config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + ''' 1999 #include <sys/mman.h> 2000 #include <stddef.h> 2001 int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) 2002 2003config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + ''' 2004 #include <pthread.h> 2005 2006 static void *f(void *p) { return NULL; } 2007 int main(void) 2008 { 2009 pthread_t thread; 2010 pthread_create(&thread, 0, f, 0); 2011 pthread_setname_np(thread, "QEMU"); 2012 return 0; 2013 }''', dependencies: threads)) 2014config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + ''' 2015 #include <pthread.h> 2016 2017 static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } 2018 int main(void) 2019 { 2020 pthread_t thread; 2021 pthread_create(&thread, 0, f, 0); 2022 return 0; 2023 }''', dependencies: threads)) 2024config_host_data.set('CONFIG_PTHREAD_CONDATTR_SETCLOCK', cc.links(gnu_source_prefix + ''' 2025 #include <pthread.h> 2026 #include <time.h> 2027 2028 int main(void) 2029 { 2030 pthread_condattr_t attr 2031 pthread_condattr_init(&attr); 2032 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 2033 return 0; 2034 }''', dependencies: threads)) 2035 2036config_host_data.set('CONFIG_SIGNALFD', cc.links(gnu_source_prefix + ''' 2037 #include <sys/signalfd.h> 2038 #include <stddef.h> 2039 int main(void) { return signalfd(-1, NULL, SFD_CLOEXEC); }''')) 2040config_host_data.set('CONFIG_SPLICE', cc.links(gnu_source_prefix + ''' 2041 #include <unistd.h> 2042 #include <fcntl.h> 2043 #include <limits.h> 2044 2045 int main(void) 2046 { 2047 int len, fd = 0; 2048 len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); 2049 splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); 2050 return 0; 2051 }''')) 2052 2053config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + ''' 2054 #include <sys/mman.h> 2055 int main(int argc, char *argv[]) { 2056 return mlockall(MCL_FUTURE); 2057 }''')) 2058 2059have_l2tpv3 = false 2060if get_option('l2tpv3').allowed() and have_system 2061 have_l2tpv3 = cc.has_type('struct mmsghdr', 2062 prefix: gnu_source_prefix + ''' 2063 #include <sys/socket.h> 2064 #include <linux/ip.h>''') 2065endif 2066config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) 2067 2068have_netmap = false 2069if get_option('netmap').allowed() and have_system 2070 have_netmap = cc.compiles(''' 2071 #include <inttypes.h> 2072 #include <net/if.h> 2073 #include <net/netmap.h> 2074 #include <net/netmap_user.h> 2075 #if (NETMAP_API < 11) || (NETMAP_API > 15) 2076 #error 2077 #endif 2078 int main(void) { return 0; }''') 2079 if not have_netmap and get_option('netmap').enabled() 2080 error('Netmap headers not available') 2081 endif 2082endif 2083config_host_data.set('CONFIG_NETMAP', have_netmap) 2084 2085# Work around a system header bug with some kernel/XFS header 2086# versions where they both try to define 'struct fsxattr': 2087# xfs headers will not try to redefine structs from linux headers 2088# if this macro is set. 2089config_host_data.set('HAVE_FSXATTR', cc.links(''' 2090 #include <linux/fs.h> 2091 struct fsxattr foo; 2092 int main(void) { 2093 return 0; 2094 }''')) 2095 2096# Some versions of Mac OS X incorrectly define SIZE_MAX 2097config_host_data.set('HAVE_BROKEN_SIZE_MAX', not cc.compiles(''' 2098 #include <stdint.h> 2099 #include <stdio.h> 2100 int main(int argc, char *argv[]) { 2101 return printf("%zu", SIZE_MAX); 2102 }''', args: ['-Werror'])) 2103 2104atomic_test = ''' 2105 #include <stdint.h> 2106 int main(void) 2107 { 2108 @0@ x = 0, y = 0; 2109 y = __atomic_load_n(&x, __ATOMIC_RELAXED); 2110 __atomic_store_n(&x, y, __ATOMIC_RELAXED); 2111 __atomic_compare_exchange_n(&x, &y, x, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2112 __atomic_exchange_n(&x, y, __ATOMIC_RELAXED); 2113 __atomic_fetch_add(&x, y, __ATOMIC_RELAXED); 2114 return 0; 2115 }''' 2116 2117# See if 64-bit atomic operations are supported. 2118# Note that without __atomic builtins, we can only 2119# assume atomic loads/stores max at pointer size. 2120config_host_data.set('CONFIG_ATOMIC64', cc.links(atomic_test.format('uint64_t'))) 2121 2122has_int128 = cc.links(''' 2123 __int128_t a; 2124 __uint128_t b; 2125 int main (void) { 2126 a = a + b; 2127 b = a * b; 2128 a = a * a; 2129 return 0; 2130 }''') 2131 2132config_host_data.set('CONFIG_INT128', has_int128) 2133 2134if has_int128 2135 # "do we have 128-bit atomics which are handled inline and specifically not 2136 # via libatomic". The reason we can't use libatomic is documented in the 2137 # comment starting "GCC is a house divided" in include/qemu/atomic128.h. 2138 has_atomic128 = cc.links(atomic_test.format('unsigned __int128')) 2139 2140 config_host_data.set('CONFIG_ATOMIC128', has_atomic128) 2141 2142 if not has_atomic128 2143 has_cmpxchg128 = cc.links(''' 2144 int main(void) 2145 { 2146 unsigned __int128 x = 0, y = 0; 2147 __sync_val_compare_and_swap_16(&x, y, x); 2148 return 0; 2149 } 2150 ''') 2151 2152 config_host_data.set('CONFIG_CMPXCHG128', has_cmpxchg128) 2153 endif 2154endif 2155 2156config_host_data.set('CONFIG_GETAUXVAL', cc.links(gnu_source_prefix + ''' 2157 #include <sys/auxv.h> 2158 int main(void) { 2159 return getauxval(AT_HWCAP) == 0; 2160 }''')) 2161 2162config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles(''' 2163 #include <linux/usbdevice_fs.h> 2164 2165 #ifndef USBDEVFS_GET_CAPABILITIES 2166 #error "USBDEVFS_GET_CAPABILITIES undefined" 2167 #endif 2168 2169 #ifndef USBDEVFS_DISCONNECT_CLAIM 2170 #error "USBDEVFS_DISCONNECT_CLAIM undefined" 2171 #endif 2172 2173 int main(void) { return 0; }''')) 2174 2175have_keyring = get_option('keyring') \ 2176 .require(targetos == 'linux', error_message: 'keyring is only available on Linux') \ 2177 .require(cc.compiles(''' 2178 #include <errno.h> 2179 #include <asm/unistd.h> 2180 #include <linux/keyctl.h> 2181 #include <sys/syscall.h> 2182 #include <unistd.h> 2183 int main(void) { 2184 return syscall(__NR_keyctl, KEYCTL_READ, 0, NULL, NULL, 0); 2185 }'''), error_message: 'keyctl syscall not available on this system').allowed() 2186config_host_data.set('CONFIG_SECRET_KEYRING', have_keyring) 2187 2188have_cpuid_h = cc.links(''' 2189 #include <cpuid.h> 2190 int main(void) { 2191 unsigned a, b, c, d; 2192 unsigned max = __get_cpuid_max(0, 0); 2193 2194 if (max >= 1) { 2195 __cpuid(1, a, b, c, d); 2196 } 2197 2198 if (max >= 7) { 2199 __cpuid_count(7, 0, a, b, c, d); 2200 } 2201 2202 return 0; 2203 }''') 2204config_host_data.set('CONFIG_CPUID_H', have_cpuid_h) 2205 2206config_host_data.set('CONFIG_AVX2_OPT', get_option('avx2') \ 2207 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX2') \ 2208 .require(cc.links(''' 2209 #pragma GCC push_options 2210 #pragma GCC target("avx2") 2211 #include <cpuid.h> 2212 #include <immintrin.h> 2213 static int bar(void *a) { 2214 __m256i x = *(__m256i *)a; 2215 return _mm256_testz_si256(x, x); 2216 } 2217 int main(int argc, char *argv[]) { return bar(argv[0]); } 2218 '''), error_message: 'AVX2 not available').allowed()) 2219 2220config_host_data.set('CONFIG_AVX512F_OPT', get_option('avx512f') \ 2221 .require(have_cpuid_h, error_message: 'cpuid.h not available, cannot enable AVX512F') \ 2222 .require(cc.links(''' 2223 #pragma GCC push_options 2224 #pragma GCC target("avx512f") 2225 #include <cpuid.h> 2226 #include <immintrin.h> 2227 static int bar(void *a) { 2228 __m512i x = *(__m512i *)a; 2229 return _mm512_test_epi64_mask(x, x); 2230 } 2231 int main(int argc, char *argv[]) { return bar(argv[0]); } 2232 '''), error_message: 'AVX512F not available').allowed()) 2233 2234have_pvrdma = get_option('pvrdma') \ 2235 .require(rdma.found(), error_message: 'PVRDMA requires OpenFabrics libraries') \ 2236 .require(cc.compiles(gnu_source_prefix + ''' 2237 #include <sys/mman.h> 2238 int main(void) 2239 { 2240 char buf = 0; 2241 void *addr = &buf; 2242 addr = mremap(addr, 0, 1, MREMAP_MAYMOVE | MREMAP_FIXED); 2243 2244 return 0; 2245 }'''), error_message: 'PVRDMA requires mremap').allowed() 2246 2247if have_pvrdma 2248 config_host_data.set('LEGACY_RDMA_REG_MR', not cc.links(''' 2249 #include <infiniband/verbs.h> 2250 int main(void) 2251 { 2252 struct ibv_mr *mr; 2253 struct ibv_pd *pd = NULL; 2254 size_t length = 10; 2255 uint64_t iova = 0; 2256 int access = 0; 2257 void *addr = NULL; 2258 2259 mr = ibv_reg_mr_iova(pd, addr, length, iova, access); 2260 ibv_dereg_mr(mr); 2261 return 0; 2262 }''')) 2263endif 2264 2265if get_option('membarrier').disabled() 2266 have_membarrier = false 2267elif targetos == 'windows' 2268 have_membarrier = true 2269elif targetos == 'linux' 2270 have_membarrier = cc.compiles(''' 2271 #include <linux/membarrier.h> 2272 #include <sys/syscall.h> 2273 #include <unistd.h> 2274 #include <stdlib.h> 2275 int main(void) { 2276 syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0); 2277 syscall(__NR_membarrier, MEMBARRIER_CMD_SHARED, 0); 2278 exit(0); 2279 }''') 2280endif 2281config_host_data.set('CONFIG_MEMBARRIER', get_option('membarrier') \ 2282 .require(have_membarrier, error_message: 'membarrier system call not available') \ 2283 .allowed()) 2284 2285have_afalg = get_option('crypto_afalg') \ 2286 .require(cc.compiles(gnu_source_prefix + ''' 2287 #include <errno.h> 2288 #include <sys/types.h> 2289 #include <sys/socket.h> 2290 #include <linux/if_alg.h> 2291 int main(void) { 2292 int sock; 2293 sock = socket(AF_ALG, SOCK_SEQPACKET, 0); 2294 return sock; 2295 } 2296 '''), error_message: 'AF_ALG requested but could not be detected').allowed() 2297config_host_data.set('CONFIG_AF_ALG', have_afalg) 2298 2299config_host_data.set('CONFIG_AF_VSOCK', cc.has_header_symbol( 2300 'linux/vm_sockets.h', 'AF_VSOCK', 2301 prefix: '#include <sys/socket.h>', 2302)) 2303 2304have_vss = false 2305have_vss_sdk = false # old xp/2003 SDK 2306if targetos == 'windows' and link_language == 'cpp' 2307 have_vss = cxx.compiles(''' 2308 #define __MIDL_user_allocate_free_DEFINED__ 2309 #include <vss.h> 2310 int main(void) { return VSS_CTX_BACKUP; }''') 2311 have_vss_sdk = cxx.has_header('vscoordint.h') 2312endif 2313config_host_data.set('HAVE_VSS_SDK', have_vss_sdk) 2314 2315foreach k, v: config_host 2316 if k.startswith('CONFIG_') 2317 config_host_data.set(k, v == 'y' ? 1 : v) 2318 endif 2319endforeach 2320 2321# Older versions of MinGW do not import _lock_file and _unlock_file properly. 2322# This was fixed for v6.0.0 with commit b48e3ac8969d. 2323if targetos == 'windows' 2324 config_host_data.set('HAVE__LOCK_FILE', cc.links(''' 2325 #include <stdio.h> 2326 int main(void) { 2327 _lock_file(NULL); 2328 _unlock_file(NULL); 2329 return 0; 2330 }''', name: '_lock_file and _unlock_file')) 2331endif 2332 2333######################## 2334# Target configuration # 2335######################## 2336 2337minikconf = find_program('scripts/minikconf.py') 2338config_all = {} 2339config_all_devices = {} 2340config_all_disas = {} 2341config_devices_mak_list = [] 2342config_devices_h = {} 2343config_target_h = {} 2344config_target_mak = {} 2345 2346disassemblers = { 2347 'alpha' : ['CONFIG_ALPHA_DIS'], 2348 'arm' : ['CONFIG_ARM_DIS'], 2349 'avr' : ['CONFIG_AVR_DIS'], 2350 'cris' : ['CONFIG_CRIS_DIS'], 2351 'hexagon' : ['CONFIG_HEXAGON_DIS'], 2352 'hppa' : ['CONFIG_HPPA_DIS'], 2353 'i386' : ['CONFIG_I386_DIS'], 2354 'x86_64' : ['CONFIG_I386_DIS'], 2355 'm68k' : ['CONFIG_M68K_DIS'], 2356 'microblaze' : ['CONFIG_MICROBLAZE_DIS'], 2357 'mips' : ['CONFIG_MIPS_DIS'], 2358 'nios2' : ['CONFIG_NIOS2_DIS'], 2359 'or1k' : ['CONFIG_OPENRISC_DIS'], 2360 'ppc' : ['CONFIG_PPC_DIS'], 2361 'riscv' : ['CONFIG_RISCV_DIS'], 2362 'rx' : ['CONFIG_RX_DIS'], 2363 's390' : ['CONFIG_S390_DIS'], 2364 'sh4' : ['CONFIG_SH4_DIS'], 2365 'sparc' : ['CONFIG_SPARC_DIS'], 2366 'xtensa' : ['CONFIG_XTENSA_DIS'], 2367 'loongarch' : ['CONFIG_LOONGARCH_DIS'], 2368} 2369if link_language == 'cpp' 2370 disassemblers += { 2371 'aarch64' : [ 'CONFIG_ARM_A64_DIS'], 2372 'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'], 2373 'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'], 2374 } 2375endif 2376 2377have_ivshmem = config_host_data.get('CONFIG_EVENTFD') 2378host_kconfig = \ 2379 (get_option('fuzzing') ? ['CONFIG_FUZZ=y'] : []) + \ 2380 (have_tpm ? ['CONFIG_TPM=y'] : []) + \ 2381 (spice.found() ? ['CONFIG_SPICE=y'] : []) + \ 2382 (have_ivshmem ? ['CONFIG_IVSHMEM=y'] : []) + \ 2383 (opengl.found() ? ['CONFIG_OPENGL=y'] : []) + \ 2384 (x11.found() ? ['CONFIG_X11=y'] : []) + \ 2385 (have_vhost_user ? ['CONFIG_VHOST_USER=y'] : []) + \ 2386 (have_vhost_vdpa ? ['CONFIG_VHOST_VDPA=y'] : []) + \ 2387 (have_vhost_kernel ? ['CONFIG_VHOST_KERNEL=y'] : []) + \ 2388 (have_virtfs ? ['CONFIG_VIRTFS=y'] : []) + \ 2389 ('CONFIG_LINUX' in config_host ? ['CONFIG_LINUX=y'] : []) + \ 2390 (have_pvrdma ? ['CONFIG_PVRDMA=y'] : []) + \ 2391 (multiprocess_allowed ? ['CONFIG_MULTIPROCESS_ALLOWED=y'] : []) + \ 2392 (vfio_user_server_allowed ? ['CONFIG_VFIO_USER_SERVER_ALLOWED=y'] : []) 2393 2394ignored = [ 'TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_ARCH' ] 2395 2396default_targets = 'CONFIG_DEFAULT_TARGETS' in config_host 2397actual_target_dirs = [] 2398fdt_required = [] 2399foreach target : target_dirs 2400 config_target = { 'TARGET_NAME': target.split('-')[0] } 2401 if target.endswith('linux-user') 2402 if targetos != 'linux' 2403 if default_targets 2404 continue 2405 endif 2406 error('Target @0@ is only available on a Linux host'.format(target)) 2407 endif 2408 config_target += { 'CONFIG_LINUX_USER': 'y' } 2409 elif target.endswith('bsd-user') 2410 if 'CONFIG_BSD' not in config_host 2411 if default_targets 2412 continue 2413 endif 2414 error('Target @0@ is only available on a BSD host'.format(target)) 2415 endif 2416 config_target += { 'CONFIG_BSD_USER': 'y' } 2417 elif target.endswith('softmmu') 2418 config_target += { 'CONFIG_SOFTMMU': 'y' } 2419 endif 2420 if target.endswith('-user') 2421 config_target += { 2422 'CONFIG_USER_ONLY': 'y', 2423 'CONFIG_QEMU_INTERP_PREFIX': 2424 get_option('interp_prefix').replace('%M', config_target['TARGET_NAME']) 2425 } 2426 endif 2427 2428 accel_kconfig = [] 2429 foreach sym: accelerators 2430 if sym == 'CONFIG_TCG' or target in accelerator_targets.get(sym, []) 2431 config_target += { sym: 'y' } 2432 config_all += { sym: 'y' } 2433 if sym == 'CONFIG_TCG' and tcg_arch == 'tci' 2434 config_target += { 'CONFIG_TCG_INTERPRETER': 'y' } 2435 endif 2436 if target in modular_tcg 2437 config_target += { 'CONFIG_TCG_MODULAR': 'y' } 2438 else 2439 config_target += { 'CONFIG_TCG_BUILTIN': 'y' } 2440 endif 2441 accel_kconfig += [ sym + '=y' ] 2442 endif 2443 endforeach 2444 if accel_kconfig.length() == 0 2445 if default_targets 2446 continue 2447 endif 2448 error('No accelerator available for target @0@'.format(target)) 2449 endif 2450 2451 actual_target_dirs += target 2452 config_target += keyval.load('configs/targets' / target + '.mak') 2453 config_target += { 'TARGET_' + config_target['TARGET_ARCH'].to_upper(): 'y' } 2454 2455 if 'TARGET_NEED_FDT' in config_target 2456 fdt_required += target 2457 endif 2458 2459 # Add default keys 2460 if 'TARGET_BASE_ARCH' not in config_target 2461 config_target += {'TARGET_BASE_ARCH': config_target['TARGET_ARCH']} 2462 endif 2463 if 'TARGET_ABI_DIR' not in config_target 2464 config_target += {'TARGET_ABI_DIR': config_target['TARGET_ARCH']} 2465 endif 2466 if 'TARGET_BIG_ENDIAN' not in config_target 2467 config_target += {'TARGET_BIG_ENDIAN': 'n'} 2468 endif 2469 2470 foreach k, v: disassemblers 2471 if host_arch.startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k) 2472 foreach sym: v 2473 config_target += { sym: 'y' } 2474 config_all_disas += { sym: 'y' } 2475 endforeach 2476 endif 2477 endforeach 2478 2479 config_target_data = configuration_data() 2480 foreach k, v: config_target 2481 if not k.startswith('TARGET_') and not k.startswith('CONFIG_') 2482 # do nothing 2483 elif ignored.contains(k) 2484 # do nothing 2485 elif k == 'TARGET_BASE_ARCH' 2486 # Note that TARGET_BASE_ARCH ends up in config-target.h but it is 2487 # not used to select files from sourcesets. 2488 config_target_data.set('TARGET_' + v.to_upper(), 1) 2489 elif k == 'TARGET_NAME' or k == 'CONFIG_QEMU_INTERP_PREFIX' 2490 config_target_data.set_quoted(k, v) 2491 elif v == 'y' 2492 config_target_data.set(k, 1) 2493 elif v == 'n' 2494 config_target_data.set(k, 0) 2495 else 2496 config_target_data.set(k, v) 2497 endif 2498 endforeach 2499 config_target_data.set('QEMU_ARCH', 2500 'QEMU_ARCH_' + config_target['TARGET_BASE_ARCH'].to_upper()) 2501 config_target_h += {target: configure_file(output: target + '-config-target.h', 2502 configuration: config_target_data)} 2503 2504 if target.endswith('-softmmu') 2505 config_input = meson.get_external_property(target, 'default') 2506 config_devices_mak = target + '-config-devices.mak' 2507 config_devices_mak = configure_file( 2508 input: ['configs/devices' / target / config_input + '.mak', 'Kconfig'], 2509 output: config_devices_mak, 2510 depfile: config_devices_mak + '.d', 2511 capture: true, 2512 command: [minikconf, 2513 get_option('default_devices') ? '--defconfig' : '--allnoconfig', 2514 config_devices_mak, '@DEPFILE@', '@INPUT@', 2515 host_kconfig, accel_kconfig, 2516 'CONFIG_' + config_target['TARGET_ARCH'].to_upper() + '=y']) 2517 2518 config_devices_data = configuration_data() 2519 config_devices = keyval.load(config_devices_mak) 2520 foreach k, v: config_devices 2521 config_devices_data.set(k, 1) 2522 endforeach 2523 config_devices_mak_list += config_devices_mak 2524 config_devices_h += {target: configure_file(output: target + '-config-devices.h', 2525 configuration: config_devices_data)} 2526 config_target += config_devices 2527 config_all_devices += config_devices 2528 endif 2529 config_target_mak += {target: config_target} 2530endforeach 2531target_dirs = actual_target_dirs 2532 2533# This configuration is used to build files that are shared by 2534# multiple binaries, and then extracted out of the "common" 2535# static_library target. 2536# 2537# We do not use all_sources()/all_dependencies(), because it would 2538# build literally all source files, including devices only used by 2539# targets that are not built for this compilation. The CONFIG_ALL 2540# pseudo symbol replaces it. 2541 2542config_all += config_all_devices 2543config_all += config_host 2544config_all += config_all_disas 2545config_all += { 2546 'CONFIG_XEN': xen.found(), 2547 'CONFIG_SOFTMMU': have_system, 2548 'CONFIG_USER_ONLY': have_user, 2549 'CONFIG_ALL': true, 2550} 2551 2552target_configs_h = [] 2553foreach target: target_dirs 2554 target_configs_h += config_target_h[target] 2555 target_configs_h += config_devices_h.get(target, []) 2556endforeach 2557genh += custom_target('config-poison.h', 2558 input: [target_configs_h], 2559 output: 'config-poison.h', 2560 capture: true, 2561 command: [find_program('scripts/make-config-poison.sh'), 2562 target_configs_h]) 2563 2564############## 2565# Submodules # 2566############## 2567 2568capstone = not_found 2569if not get_option('capstone').auto() or have_system or have_user 2570 capstone = dependency('capstone', version: '>=3.0.5', 2571 kwargs: static_kwargs, method: 'pkg-config', 2572 required: get_option('capstone')) 2573 2574 # Some versions of capstone have broken pkg-config file 2575 # that reports a wrong -I path, causing the #include to 2576 # fail later. If the system has such a broken version 2577 # do not use it. 2578 if capstone.found() and not cc.compiles('#include <capstone.h>', 2579 dependencies: [capstone]) 2580 capstone = not_found 2581 if get_option('capstone').enabled() 2582 error('capstone requested, but it does not appear to work') 2583 endif 2584 endif 2585endif 2586 2587slirp = not_found 2588slirp_opt = 'disabled' 2589if have_system 2590 slirp_opt = get_option('slirp') 2591 if slirp_opt in ['enabled', 'auto', 'system'] 2592 have_internal = fs.exists(meson.current_source_dir() / 'slirp/meson.build') 2593 slirp_dep_required = (slirp_opt == 'system' or 2594 slirp_opt == 'enabled' and not have_internal) 2595 slirp = dependency('slirp', kwargs: static_kwargs, 2596 method: 'pkg-config', version: '>=4.1.0', 2597 required: slirp_dep_required) 2598 # slirp <4.7 is incompatible with CFI support in QEMU. This is because 2599 # it passes function pointers within libslirp as callbacks for timers. 2600 # When using a system-wide shared libslirp, the type information for the 2601 # callback is missing and the timer call produces a false positive with CFI. 2602 # Do not use the "version" keyword argument to produce a better error. 2603 # with control-flow integrity. 2604 if get_option('cfi') and slirp.found() and slirp.version().version_compare('<4.7') 2605 if slirp_dep_required 2606 error('Control-Flow Integrity requires libslirp 4.7.') 2607 else 2608 warning('Control-Flow Integrity requires libslirp 4.7, not using system-wide libslirp.') 2609 slirp = not_found 2610 endif 2611 endif 2612 if slirp.found() 2613 slirp_opt = 'system' 2614 elif have_internal 2615 slirp_opt = 'internal' 2616 else 2617 slirp_opt = 'disabled' 2618 endif 2619 endif 2620 if slirp_opt == 'internal' 2621 slirp_deps = [] 2622 if targetos == 'windows' 2623 slirp_deps = cc.find_library('iphlpapi') 2624 elif targetos == 'darwin' 2625 slirp_deps = cc.find_library('resolv') 2626 endif 2627 slirp_conf = configuration_data() 2628 slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) 2629 slirp_conf.set('SLIRP_MINOR_VERSION', meson.project_version().split('.')[1]) 2630 slirp_conf.set('SLIRP_MICRO_VERSION', meson.project_version().split('.')[2]) 2631 slirp_conf.set_quoted('SLIRP_VERSION_STRING', meson.project_version()) 2632 slirp_cargs = ['-DG_LOG_DOMAIN="Slirp"'] 2633 slirp_files = [ 2634 'slirp/src/arp_table.c', 2635 'slirp/src/bootp.c', 2636 'slirp/src/cksum.c', 2637 'slirp/src/dhcpv6.c', 2638 'slirp/src/dnssearch.c', 2639 'slirp/src/if.c', 2640 'slirp/src/ip6_icmp.c', 2641 'slirp/src/ip6_input.c', 2642 'slirp/src/ip6_output.c', 2643 'slirp/src/ip_icmp.c', 2644 'slirp/src/ip_input.c', 2645 'slirp/src/ip_output.c', 2646 'slirp/src/mbuf.c', 2647 'slirp/src/misc.c', 2648 'slirp/src/ncsi.c', 2649 'slirp/src/ndp_table.c', 2650 'slirp/src/sbuf.c', 2651 'slirp/src/slirp.c', 2652 'slirp/src/socket.c', 2653 'slirp/src/state.c', 2654 'slirp/src/stream.c', 2655 'slirp/src/tcp_input.c', 2656 'slirp/src/tcp_output.c', 2657 'slirp/src/tcp_subr.c', 2658 'slirp/src/tcp_timer.c', 2659 'slirp/src/tftp.c', 2660 'slirp/src/udp.c', 2661 'slirp/src/udp6.c', 2662 'slirp/src/util.c', 2663 'slirp/src/version.c', 2664 'slirp/src/vmstate.c', 2665 ] 2666 2667 configure_file( 2668 input : 'slirp/src/libslirp-version.h.in', 2669 output : 'libslirp-version.h', 2670 configuration: slirp_conf) 2671 2672 slirp_inc = include_directories('slirp', 'slirp/src') 2673 libslirp = static_library('slirp', 2674 build_by_default: false, 2675 sources: slirp_files, 2676 c_args: slirp_cargs, 2677 include_directories: slirp_inc) 2678 slirp = declare_dependency(link_with: libslirp, 2679 dependencies: slirp_deps, 2680 include_directories: slirp_inc) 2681 endif 2682endif 2683 2684libvfio_user_dep = not_found 2685if have_system and vfio_user_server_allowed 2686 have_internal = fs.exists(meson.current_source_dir() / 'subprojects/libvfio-user/meson.build') 2687 2688 if not have_internal 2689 error('libvfio-user source not found - please pull git submodule') 2690 endif 2691 2692 libvfio_user_proj = subproject('libvfio-user') 2693 2694 libvfio_user_lib = libvfio_user_proj.get_variable('libvfio_user_dep') 2695 2696 libvfio_user_dep = declare_dependency(dependencies: [libvfio_user_lib]) 2697endif 2698 2699fdt = not_found 2700if have_system 2701 fdt_opt = get_option('fdt') 2702 if fdt_opt in ['enabled', 'auto', 'system'] 2703 have_internal = fs.exists(meson.current_source_dir() / 'dtc/libfdt/Makefile.libfdt') 2704 fdt = cc.find_library('fdt', kwargs: static_kwargs, 2705 required: fdt_opt == 'system' or 2706 fdt_opt == 'enabled' and not have_internal) 2707 if fdt.found() and cc.links(''' 2708 #include <libfdt.h> 2709 #include <libfdt_env.h> 2710 int main(void) { fdt_find_max_phandle(NULL, NULL); return 0; }''', 2711 dependencies: fdt) 2712 fdt_opt = 'system' 2713 elif fdt_opt == 'system' 2714 error('system libfdt requested, but it is too old (1.5.1 or newer required)') 2715 elif have_internal 2716 fdt_opt = 'internal' 2717 else 2718 fdt_opt = 'disabled' 2719 fdt = not_found 2720 endif 2721 endif 2722 if fdt_opt == 'internal' 2723 fdt_files = files( 2724 'dtc/libfdt/fdt.c', 2725 'dtc/libfdt/fdt_ro.c', 2726 'dtc/libfdt/fdt_wip.c', 2727 'dtc/libfdt/fdt_sw.c', 2728 'dtc/libfdt/fdt_rw.c', 2729 'dtc/libfdt/fdt_strerror.c', 2730 'dtc/libfdt/fdt_empty_tree.c', 2731 'dtc/libfdt/fdt_addresses.c', 2732 'dtc/libfdt/fdt_overlay.c', 2733 'dtc/libfdt/fdt_check.c', 2734 ) 2735 2736 fdt_inc = include_directories('dtc/libfdt') 2737 libfdt = static_library('fdt', 2738 build_by_default: false, 2739 sources: fdt_files, 2740 include_directories: fdt_inc) 2741 fdt = declare_dependency(link_with: libfdt, 2742 include_directories: fdt_inc) 2743 endif 2744else 2745 fdt_opt = 'disabled' 2746endif 2747if not fdt.found() and fdt_required.length() > 0 2748 error('fdt not available but required by targets ' + ', '.join(fdt_required)) 2749endif 2750 2751config_host_data.set('CONFIG_CAPSTONE', capstone.found()) 2752config_host_data.set('CONFIG_FDT', fdt.found()) 2753config_host_data.set('CONFIG_SLIRP', slirp.found()) 2754 2755##################### 2756# Generated sources # 2757##################### 2758 2759genh += configure_file(output: 'config-host.h', configuration: config_host_data) 2760 2761hxtool = find_program('scripts/hxtool') 2762shaderinclude = find_program('scripts/shaderinclude.pl') 2763qapi_gen = find_program('scripts/qapi-gen.py') 2764qapi_gen_depends = [ meson.current_source_dir() / 'scripts/qapi/__init__.py', 2765 meson.current_source_dir() / 'scripts/qapi/commands.py', 2766 meson.current_source_dir() / 'scripts/qapi/common.py', 2767 meson.current_source_dir() / 'scripts/qapi/error.py', 2768 meson.current_source_dir() / 'scripts/qapi/events.py', 2769 meson.current_source_dir() / 'scripts/qapi/expr.py', 2770 meson.current_source_dir() / 'scripts/qapi/gen.py', 2771 meson.current_source_dir() / 'scripts/qapi/introspect.py', 2772 meson.current_source_dir() / 'scripts/qapi/parser.py', 2773 meson.current_source_dir() / 'scripts/qapi/schema.py', 2774 meson.current_source_dir() / 'scripts/qapi/source.py', 2775 meson.current_source_dir() / 'scripts/qapi/types.py', 2776 meson.current_source_dir() / 'scripts/qapi/visit.py', 2777 meson.current_source_dir() / 'scripts/qapi/common.py', 2778 meson.current_source_dir() / 'scripts/qapi-gen.py' 2779] 2780 2781tracetool = [ 2782 python, files('scripts/tracetool.py'), 2783 '--backend=' + ','.join(get_option('trace_backends')) 2784] 2785tracetool_depends = files( 2786 'scripts/tracetool/backend/log.py', 2787 'scripts/tracetool/backend/__init__.py', 2788 'scripts/tracetool/backend/dtrace.py', 2789 'scripts/tracetool/backend/ftrace.py', 2790 'scripts/tracetool/backend/simple.py', 2791 'scripts/tracetool/backend/syslog.py', 2792 'scripts/tracetool/backend/ust.py', 2793 'scripts/tracetool/format/ust_events_c.py', 2794 'scripts/tracetool/format/ust_events_h.py', 2795 'scripts/tracetool/format/__init__.py', 2796 'scripts/tracetool/format/d.py', 2797 'scripts/tracetool/format/simpletrace_stap.py', 2798 'scripts/tracetool/format/c.py', 2799 'scripts/tracetool/format/h.py', 2800 'scripts/tracetool/format/log_stap.py', 2801 'scripts/tracetool/format/stap.py', 2802 'scripts/tracetool/__init__.py', 2803 'scripts/tracetool/transform.py', 2804 'scripts/tracetool/vcpu.py' 2805) 2806 2807qemu_version_cmd = [find_program('scripts/qemu-version.sh'), 2808 meson.current_source_dir(), 2809 get_option('pkgversion'), meson.project_version()] 2810qemu_version = custom_target('qemu-version.h', 2811 output: 'qemu-version.h', 2812 command: qemu_version_cmd, 2813 capture: true, 2814 build_by_default: true, 2815 build_always_stale: true) 2816genh += qemu_version 2817 2818hxdep = [] 2819hx_headers = [ 2820 ['qemu-options.hx', 'qemu-options.def'], 2821 ['qemu-img-cmds.hx', 'qemu-img-cmds.h'], 2822] 2823if have_system 2824 hx_headers += [ 2825 ['hmp-commands.hx', 'hmp-commands.h'], 2826 ['hmp-commands-info.hx', 'hmp-commands-info.h'], 2827 ] 2828endif 2829foreach d : hx_headers 2830 hxdep += custom_target(d[1], 2831 input: files(d[0]), 2832 output: d[1], 2833 capture: true, 2834 build_by_default: true, # to be removed when added to a target 2835 command: [hxtool, '-h', '@INPUT0@']) 2836endforeach 2837genh += hxdep 2838 2839################### 2840# Collect sources # 2841################### 2842 2843authz_ss = ss.source_set() 2844blockdev_ss = ss.source_set() 2845block_ss = ss.source_set() 2846chardev_ss = ss.source_set() 2847common_ss = ss.source_set() 2848crypto_ss = ss.source_set() 2849hwcore_ss = ss.source_set() 2850io_ss = ss.source_set() 2851qmp_ss = ss.source_set() 2852qom_ss = ss.source_set() 2853softmmu_ss = ss.source_set() 2854specific_fuzz_ss = ss.source_set() 2855specific_ss = ss.source_set() 2856stub_ss = ss.source_set() 2857trace_ss = ss.source_set() 2858user_ss = ss.source_set() 2859util_ss = ss.source_set() 2860 2861# accel modules 2862qtest_module_ss = ss.source_set() 2863tcg_module_ss = ss.source_set() 2864 2865modules = {} 2866target_modules = {} 2867hw_arch = {} 2868target_arch = {} 2869target_softmmu_arch = {} 2870target_user_arch = {} 2871 2872############### 2873# Trace files # 2874############### 2875 2876# TODO: add each directory to the subdirs from its own meson.build, once 2877# we have those 2878trace_events_subdirs = [ 2879 'crypto', 2880 'qapi', 2881 'qom', 2882 'monitor', 2883 'util', 2884] 2885if have_linux_user 2886 trace_events_subdirs += [ 'linux-user' ] 2887endif 2888if have_bsd_user 2889 trace_events_subdirs += [ 'bsd-user' ] 2890endif 2891if have_block 2892 trace_events_subdirs += [ 2893 'authz', 2894 'block', 2895 'io', 2896 'nbd', 2897 'scsi', 2898 ] 2899endif 2900if have_system 2901 trace_events_subdirs += [ 2902 'accel/kvm', 2903 'audio', 2904 'backends', 2905 'backends/tpm', 2906 'chardev', 2907 'ebpf', 2908 'hw/9pfs', 2909 'hw/acpi', 2910 'hw/adc', 2911 'hw/alpha', 2912 'hw/arm', 2913 'hw/audio', 2914 'hw/block', 2915 'hw/block/dataplane', 2916 'hw/char', 2917 'hw/display', 2918 'hw/dma', 2919 'hw/hyperv', 2920 'hw/i2c', 2921 'hw/i386', 2922 'hw/i386/xen', 2923 'hw/ide', 2924 'hw/input', 2925 'hw/intc', 2926 'hw/isa', 2927 'hw/mem', 2928 'hw/mips', 2929 'hw/misc', 2930 'hw/misc/macio', 2931 'hw/net', 2932 'hw/net/can', 2933 'hw/nubus', 2934 'hw/nvme', 2935 'hw/nvram', 2936 'hw/pci', 2937 'hw/pci-host', 2938 'hw/ppc', 2939 'hw/rdma', 2940 'hw/rdma/vmw', 2941 'hw/rtc', 2942 'hw/s390x', 2943 'hw/scsi', 2944 'hw/sd', 2945 'hw/sh4', 2946 'hw/sparc', 2947 'hw/sparc64', 2948 'hw/ssi', 2949 'hw/timer', 2950 'hw/tpm', 2951 'hw/usb', 2952 'hw/vfio', 2953 'hw/virtio', 2954 'hw/watchdog', 2955 'hw/xen', 2956 'hw/gpio', 2957 'migration', 2958 'net', 2959 'softmmu', 2960 'ui', 2961 'hw/remote', 2962 ] 2963endif 2964if have_system or have_user 2965 trace_events_subdirs += [ 2966 'accel/tcg', 2967 'hw/core', 2968 'target/arm', 2969 'target/arm/hvf', 2970 'target/hppa', 2971 'target/i386', 2972 'target/i386/kvm', 2973 'target/mips/tcg', 2974 'target/nios2', 2975 'target/ppc', 2976 'target/riscv', 2977 'target/s390x', 2978 'target/s390x/kvm', 2979 'target/sparc', 2980 ] 2981endif 2982 2983vhost_user = not_found 2984if targetos == 'linux' and have_vhost_user 2985 libvhost_user = subproject('libvhost-user') 2986 vhost_user = libvhost_user.get_variable('vhost_user_dep') 2987endif 2988 2989# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 2990# that is filled in by qapi/. 2991subdir('qapi') 2992subdir('qobject') 2993subdir('stubs') 2994subdir('trace') 2995subdir('util') 2996subdir('qom') 2997subdir('authz') 2998subdir('crypto') 2999subdir('ui') 3000subdir('hw') 3001 3002 3003if enable_modules 3004 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 3005 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 3006endif 3007 3008qom_ss = qom_ss.apply(config_host, strict: false) 3009libqom = static_library('qom', qom_ss.sources() + genh, 3010 dependencies: [qom_ss.dependencies()], 3011 name_suffix: 'fa') 3012qom = declare_dependency(link_whole: libqom) 3013 3014event_loop_base = files('event-loop-base.c') 3015event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh, 3016 build_by_default: true) 3017event_loop_base = declare_dependency(link_whole: event_loop_base, 3018 dependencies: [qom]) 3019 3020stub_ss = stub_ss.apply(config_all, strict: false) 3021 3022util_ss.add_all(trace_ss) 3023util_ss = util_ss.apply(config_all, strict: false) 3024libqemuutil = static_library('qemuutil', 3025 sources: util_ss.sources() + stub_ss.sources() + genh, 3026 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman]) 3027qemuutil = declare_dependency(link_with: libqemuutil, 3028 sources: genh + version_res, 3029 dependencies: [event_loop_base]) 3030 3031if have_system or have_user 3032 decodetree = generator(find_program('scripts/decodetree.py'), 3033 output: 'decode-@BASENAME@.c.inc', 3034 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3035 subdir('libdecnumber') 3036 subdir('target') 3037endif 3038 3039subdir('audio') 3040subdir('io') 3041subdir('chardev') 3042subdir('fsdev') 3043subdir('dump') 3044 3045if have_block 3046 block_ss.add(files( 3047 'block.c', 3048 'blockjob.c', 3049 'job.c', 3050 'qemu-io-cmds.c', 3051 )) 3052 if config_host_data.get('CONFIG_REPLICATION') 3053 block_ss.add(files('replication.c')) 3054 endif 3055 3056 subdir('nbd') 3057 subdir('scsi') 3058 subdir('block') 3059 3060 blockdev_ss.add(files( 3061 'blockdev.c', 3062 'blockdev-nbd.c', 3063 'iothread.c', 3064 'job-qmp.c', 3065 ), gnutls) 3066 3067 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3068 # os-win32.c does not 3069 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 3070 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 3071endif 3072 3073common_ss.add(files('cpus-common.c')) 3074 3075subdir('softmmu') 3076 3077common_ss.add(capstone) 3078specific_ss.add(files('cpu.c', 'disas.c', 'gdbstub.c'), capstone) 3079 3080# Work around a gcc bug/misfeature wherein constant propagation looks 3081# through an alias: 3082# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3083# to guess that a const variable is always zero. Without lto, this is 3084# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3085# without lto, not even the alias is required -- we simply use different 3086# declarations in different compilation units. 3087pagevary = files('page-vary-common.c') 3088if get_option('b_lto') 3089 pagevary_flags = ['-fno-lto'] 3090 if get_option('cfi') 3091 pagevary_flags += '-fno-sanitize=cfi-icall' 3092 endif 3093 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3094 c_args: pagevary_flags) 3095 pagevary = declare_dependency(link_with: pagevary) 3096endif 3097common_ss.add(pagevary) 3098specific_ss.add(files('page-vary.c')) 3099 3100subdir('backends') 3101subdir('disas') 3102subdir('migration') 3103subdir('monitor') 3104subdir('net') 3105subdir('replay') 3106subdir('semihosting') 3107subdir('tcg') 3108subdir('fpu') 3109subdir('accel') 3110subdir('plugins') 3111subdir('ebpf') 3112 3113common_user_inc = [] 3114 3115subdir('common-user') 3116subdir('bsd-user') 3117subdir('linux-user') 3118 3119# needed for fuzzing binaries 3120subdir('tests/qtest/libqos') 3121subdir('tests/qtest/fuzz') 3122 3123# accel modules 3124tcg_real_module_ss = ss.source_set() 3125tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3126specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3127target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3128 'tcg': tcg_real_module_ss }} 3129 3130######################## 3131# Library dependencies # 3132######################## 3133 3134modinfo_collect = find_program('scripts/modinfo-collect.py') 3135modinfo_generate = find_program('scripts/modinfo-generate.py') 3136modinfo_files = [] 3137 3138block_mods = [] 3139softmmu_mods = [] 3140foreach d, list : modules 3141 foreach m, module_ss : list 3142 if enable_modules and targetos != 'windows' 3143 module_ss = module_ss.apply(config_all, strict: false) 3144 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3145 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 3146 if d == 'block' 3147 block_mods += sl 3148 else 3149 softmmu_mods += sl 3150 endif 3151 if module_ss.sources() != [] 3152 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3153 # input. Sources can be used multiple times but objects are 3154 # unique when it comes to lookup in compile_commands.json. 3155 # Depnds on a mesion version with 3156 # https://github.com/mesonbuild/meson/pull/8900 3157 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3158 output: d + '-' + m + '.modinfo', 3159 input: module_ss.sources() + genh, 3160 capture: true, 3161 command: [modinfo_collect, module_ss.sources()]) 3162 endif 3163 else 3164 if d == 'block' 3165 block_ss.add_all(module_ss) 3166 else 3167 softmmu_ss.add_all(module_ss) 3168 endif 3169 endif 3170 endforeach 3171endforeach 3172 3173foreach d, list : target_modules 3174 foreach m, module_ss : list 3175 if enable_modules and targetos != 'windows' 3176 foreach target : target_dirs 3177 if target.endswith('-softmmu') 3178 config_target = config_target_mak[target] 3179 config_target += config_host 3180 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3181 c_args = ['-DNEED_CPU_H', 3182 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3183 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3184 target_module_ss = module_ss.apply(config_target, strict: false) 3185 if target_module_ss.sources() != [] 3186 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3187 sl = static_library(module_name, 3188 [genh, target_module_ss.sources()], 3189 dependencies: [modulecommon, target_module_ss.dependencies()], 3190 include_directories: target_inc, 3191 c_args: c_args, 3192 pic: true) 3193 softmmu_mods += sl 3194 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3195 modinfo_files += custom_target(module_name + '.modinfo', 3196 output: module_name + '.modinfo', 3197 input: target_module_ss.sources() + genh, 3198 capture: true, 3199 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3200 endif 3201 endif 3202 endforeach 3203 else 3204 specific_ss.add_all(module_ss) 3205 endif 3206 endforeach 3207endforeach 3208 3209if enable_modules 3210 foreach target : target_dirs 3211 if target.endswith('-softmmu') 3212 config_target = config_target_mak[target] 3213 config_devices_mak = target + '-config-devices.mak' 3214 modinfo_src = custom_target('modinfo-' + target + '.c', 3215 output: 'modinfo-' + target + '.c', 3216 input: modinfo_files, 3217 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3218 capture: true) 3219 3220 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3221 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3222 3223 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3224 hw_arch[arch].add(modinfo_dep) 3225 endif 3226 endforeach 3227endif 3228 3229nm = find_program('nm') 3230undefsym = find_program('scripts/undefsym.py') 3231block_syms = custom_target('block.syms', output: 'block.syms', 3232 input: [libqemuutil, block_mods], 3233 capture: true, 3234 command: [undefsym, nm, '@INPUT@']) 3235qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3236 input: [libqemuutil, softmmu_mods], 3237 capture: true, 3238 command: [undefsym, nm, '@INPUT@']) 3239 3240authz_ss = authz_ss.apply(config_host, strict: false) 3241libauthz = static_library('authz', authz_ss.sources() + genh, 3242 dependencies: [authz_ss.dependencies()], 3243 name_suffix: 'fa', 3244 build_by_default: false) 3245 3246authz = declare_dependency(link_whole: libauthz, 3247 dependencies: qom) 3248 3249crypto_ss = crypto_ss.apply(config_host, strict: false) 3250libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3251 dependencies: [crypto_ss.dependencies()], 3252 name_suffix: 'fa', 3253 build_by_default: false) 3254 3255crypto = declare_dependency(link_whole: libcrypto, 3256 dependencies: [authz, qom]) 3257 3258io_ss = io_ss.apply(config_host, strict: false) 3259libio = static_library('io', io_ss.sources() + genh, 3260 dependencies: [io_ss.dependencies()], 3261 link_with: libqemuutil, 3262 name_suffix: 'fa', 3263 build_by_default: false) 3264 3265io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 3266 3267libmigration = static_library('migration', sources: migration_files + genh, 3268 name_suffix: 'fa', 3269 build_by_default: false) 3270migration = declare_dependency(link_with: libmigration, 3271 dependencies: [zlib, qom, io]) 3272softmmu_ss.add(migration) 3273 3274block_ss = block_ss.apply(config_host, strict: false) 3275libblock = static_library('block', block_ss.sources() + genh, 3276 dependencies: block_ss.dependencies(), 3277 link_depends: block_syms, 3278 name_suffix: 'fa', 3279 build_by_default: false) 3280 3281block = declare_dependency(link_whole: [libblock], 3282 link_args: '@block.syms', 3283 dependencies: [crypto, io]) 3284 3285blockdev_ss = blockdev_ss.apply(config_host, strict: false) 3286libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3287 dependencies: blockdev_ss.dependencies(), 3288 name_suffix: 'fa', 3289 build_by_default: false) 3290 3291blockdev = declare_dependency(link_whole: [libblockdev], 3292 dependencies: [block, event_loop_base]) 3293 3294qmp_ss = qmp_ss.apply(config_host, strict: false) 3295libqmp = static_library('qmp', qmp_ss.sources() + genh, 3296 dependencies: qmp_ss.dependencies(), 3297 name_suffix: 'fa', 3298 build_by_default: false) 3299 3300qmp = declare_dependency(link_whole: [libqmp]) 3301 3302libchardev = static_library('chardev', chardev_ss.sources() + genh, 3303 name_suffix: 'fa', 3304 dependencies: chardev_ss.dependencies(), 3305 build_by_default: false) 3306 3307chardev = declare_dependency(link_whole: libchardev) 3308 3309hwcore_ss = hwcore_ss.apply(config_host, strict: false) 3310libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3311 name_suffix: 'fa', 3312 build_by_default: false) 3313hwcore = declare_dependency(link_whole: libhwcore) 3314common_ss.add(hwcore) 3315 3316########### 3317# Targets # 3318########### 3319 3320emulator_modules = [] 3321foreach m : block_mods + softmmu_mods 3322 emulator_modules += shared_module(m.name(), 3323 build_by_default: true, 3324 name_prefix: '', 3325 link_whole: m, 3326 install: true, 3327 install_dir: qemu_moddir) 3328endforeach 3329if emulator_modules.length() > 0 3330 alias_target('modules', emulator_modules) 3331endif 3332 3333softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3334common_ss.add(qom, qemuutil) 3335 3336common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 3337common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3338 3339common_all = common_ss.apply(config_all, strict: false) 3340common_all = static_library('common', 3341 build_by_default: false, 3342 sources: common_all.sources() + genh, 3343 include_directories: common_user_inc, 3344 implicit_include_directories: false, 3345 dependencies: common_all.dependencies(), 3346 name_suffix: 'fa') 3347 3348feature_to_c = find_program('scripts/feature_to_c.sh') 3349 3350if targetos == 'darwin' 3351 entitlement = find_program('scripts/entitlement.sh') 3352endif 3353 3354emulators = {} 3355foreach target : target_dirs 3356 config_target = config_target_mak[target] 3357 target_name = config_target['TARGET_NAME'] 3358 target_base_arch = config_target['TARGET_BASE_ARCH'] 3359 arch_srcs = [config_target_h[target]] 3360 arch_deps = [] 3361 c_args = ['-DNEED_CPU_H', 3362 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3363 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3364 link_args = emulator_link_args 3365 3366 config_target += config_host 3367 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3368 if targetos == 'linux' 3369 target_inc += include_directories('linux-headers', is_system: true) 3370 endif 3371 if target.endswith('-softmmu') 3372 qemu_target_name = 'qemu-system-' + target_name 3373 target_type='system' 3374 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false) 3375 arch_srcs += t.sources() 3376 arch_deps += t.dependencies() 3377 3378 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3379 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3380 arch_srcs += hw.sources() 3381 arch_deps += hw.dependencies() 3382 3383 arch_srcs += config_devices_h[target] 3384 link_args += ['@block.syms', '@qemu.syms'] 3385 else 3386 abi = config_target['TARGET_ABI_DIR'] 3387 target_type='user' 3388 target_inc += common_user_inc 3389 qemu_target_name = 'qemu-' + target_name 3390 if target_base_arch in target_user_arch 3391 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3392 arch_srcs += t.sources() 3393 arch_deps += t.dependencies() 3394 endif 3395 if 'CONFIG_LINUX_USER' in config_target 3396 base_dir = 'linux-user' 3397 endif 3398 if 'CONFIG_BSD_USER' in config_target 3399 base_dir = 'bsd-user' 3400 target_inc += include_directories('bsd-user/' / targetos) 3401 target_inc += include_directories('bsd-user/host/' / host_arch) 3402 dir = base_dir / abi 3403 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3404 endif 3405 target_inc += include_directories( 3406 base_dir, 3407 base_dir / abi, 3408 ) 3409 if 'CONFIG_LINUX_USER' in config_target 3410 dir = base_dir / abi 3411 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3412 if config_target.has_key('TARGET_SYSTBL_ABI') 3413 arch_srcs += \ 3414 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3415 extra_args : config_target['TARGET_SYSTBL_ABI']) 3416 endif 3417 endif 3418 endif 3419 3420 if 'TARGET_XML_FILES' in config_target 3421 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3422 output: target + '-gdbstub-xml.c', 3423 input: files(config_target['TARGET_XML_FILES'].split()), 3424 command: [feature_to_c, '@INPUT@'], 3425 capture: true) 3426 arch_srcs += gdbstub_xml 3427 endif 3428 3429 t = target_arch[target_base_arch].apply(config_target, strict: false) 3430 arch_srcs += t.sources() 3431 arch_deps += t.dependencies() 3432 3433 target_common = common_ss.apply(config_target, strict: false) 3434 objects = common_all.extract_objects(target_common.sources()) 3435 deps = target_common.dependencies() 3436 3437 target_specific = specific_ss.apply(config_target, strict: false) 3438 arch_srcs += target_specific.sources() 3439 arch_deps += target_specific.dependencies() 3440 3441 lib = static_library('qemu-' + target, 3442 sources: arch_srcs + genh, 3443 dependencies: arch_deps, 3444 objects: objects, 3445 include_directories: target_inc, 3446 c_args: c_args, 3447 build_by_default: false, 3448 name_suffix: 'fa') 3449 3450 if target.endswith('-softmmu') 3451 execs = [{ 3452 'name': 'qemu-system-' + target_name, 3453 'win_subsystem': 'console', 3454 'sources': files('softmmu/main.c'), 3455 'dependencies': [] 3456 }] 3457 if targetos == 'windows' and (sdl.found() or gtk.found()) 3458 execs += [{ 3459 'name': 'qemu-system-' + target_name + 'w', 3460 'win_subsystem': 'windows', 3461 'sources': files('softmmu/main.c'), 3462 'dependencies': [] 3463 }] 3464 endif 3465 if get_option('fuzzing') 3466 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 3467 execs += [{ 3468 'name': 'qemu-fuzz-' + target_name, 3469 'win_subsystem': 'console', 3470 'sources': specific_fuzz.sources(), 3471 'dependencies': specific_fuzz.dependencies(), 3472 }] 3473 endif 3474 else 3475 execs = [{ 3476 'name': 'qemu-' + target_name, 3477 'win_subsystem': 'console', 3478 'sources': [], 3479 'dependencies': [] 3480 }] 3481 endif 3482 foreach exe: execs 3483 exe_name = exe['name'] 3484 if targetos == 'darwin' 3485 exe_name += '-unsigned' 3486 endif 3487 3488 emulator = executable(exe_name, exe['sources'], 3489 install: true, 3490 c_args: c_args, 3491 dependencies: arch_deps + deps + exe['dependencies'], 3492 objects: lib.extract_all_objects(recursive: true), 3493 link_language: link_language, 3494 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 3495 link_args: link_args, 3496 win_subsystem: exe['win_subsystem']) 3497 3498 if targetos == 'darwin' 3499 icon = 'pc-bios/qemu.rsrc' 3500 build_input = [emulator, files(icon)] 3501 install_input = [ 3502 get_option('bindir') / exe_name, 3503 meson.current_source_dir() / icon 3504 ] 3505 if 'CONFIG_HVF' in config_target 3506 entitlements = 'accel/hvf/entitlements.plist' 3507 build_input += files(entitlements) 3508 install_input += meson.current_source_dir() / entitlements 3509 endif 3510 3511 emulators += {exe['name'] : custom_target(exe['name'], 3512 input: build_input, 3513 output: exe['name'], 3514 command: [entitlement, '@OUTPUT@', '@INPUT@']) 3515 } 3516 3517 meson.add_install_script(entitlement, '--install', 3518 get_option('bindir') / exe['name'], 3519 install_input) 3520 else 3521 emulators += {exe['name']: emulator} 3522 endif 3523 3524 if stap.found() 3525 foreach stp: [ 3526 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 3527 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 3528 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 3529 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 3530 ] 3531 custom_target(exe['name'] + stp['ext'], 3532 input: trace_events_all, 3533 output: exe['name'] + stp['ext'], 3534 install: stp['install'], 3535 install_dir: get_option('datadir') / 'systemtap/tapset', 3536 command: [ 3537 tracetool, '--group=all', '--format=' + stp['fmt'], 3538 '--binary=' + stp['bin'], 3539 '--target-name=' + target_name, 3540 '--target-type=' + target_type, 3541 '--probe-prefix=qemu.' + target_type + '.' + target_name, 3542 '@INPUT@', '@OUTPUT@' 3543 ], 3544 depend_files: tracetool_depends) 3545 endforeach 3546 endif 3547 endforeach 3548endforeach 3549 3550# Other build targets 3551 3552if 'CONFIG_PLUGIN' in config_host 3553 install_headers('include/qemu/qemu-plugin.h') 3554endif 3555 3556subdir('qga') 3557 3558# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3559# when we don't build tools or system 3560if xkbcommon.found() 3561 # used for the update-keymaps target, so include rules even if !have_tools 3562 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 3563 dependencies: [qemuutil, xkbcommon], install: have_tools) 3564endif 3565 3566if have_tools 3567 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 3568 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 3569 qemu_io = executable('qemu-io', files('qemu-io.c'), 3570 dependencies: [block, qemuutil], install: true) 3571 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 3572 dependencies: [blockdev, qemuutil, gnutls, selinux], 3573 install: true) 3574 3575 subdir('storage-daemon') 3576 subdir('contrib/rdmacm-mux') 3577 subdir('contrib/elf2dmp') 3578 3579 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 3580 dependencies: qemuutil, 3581 install: true) 3582 3583 if have_vhost_user 3584 subdir('contrib/vhost-user-blk') 3585 subdir('contrib/vhost-user-gpu') 3586 subdir('contrib/vhost-user-input') 3587 subdir('contrib/vhost-user-scsi') 3588 endif 3589 3590 if targetos == 'linux' 3591 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 3592 dependencies: [qemuutil, libcap_ng], 3593 install: true, 3594 install_dir: get_option('libexecdir')) 3595 3596 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 3597 dependencies: [authz, crypto, io, qom, qemuutil, 3598 libcap_ng, mpathpersist], 3599 install: true) 3600 endif 3601 3602 if have_ivshmem 3603 subdir('contrib/ivshmem-client') 3604 subdir('contrib/ivshmem-server') 3605 endif 3606endif 3607 3608subdir('scripts') 3609subdir('tools') 3610subdir('pc-bios') 3611subdir('docs') 3612subdir('tests') 3613if gtk.found() 3614 subdir('po') 3615endif 3616 3617if host_machine.system() == 'windows' 3618 nsis_cmd = [ 3619 find_program('scripts/nsis.py'), 3620 '@OUTPUT@', 3621 get_option('prefix'), 3622 meson.current_source_dir(), 3623 host_machine.cpu(), 3624 '--', 3625 '-DDISPLAYVERSION=' + meson.project_version(), 3626 ] 3627 if build_docs 3628 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 3629 endif 3630 if gtk.found() 3631 nsis_cmd += '-DCONFIG_GTK=y' 3632 endif 3633 3634 nsis = custom_target('nsis', 3635 output: 'qemu-setup-' + meson.project_version() + '.exe', 3636 input: files('qemu.nsi'), 3637 build_always_stale: true, 3638 command: nsis_cmd + ['@INPUT@']) 3639 alias_target('installer', nsis) 3640endif 3641 3642######################### 3643# Configuration summary # 3644######################### 3645 3646# Directories 3647summary_info = {} 3648summary_info += {'Install prefix': get_option('prefix')} 3649summary_info += {'BIOS directory': qemu_datadir} 3650summary_info += {'firmware path': get_option('prefix') / get_option('qemu_firmwarepath')} 3651summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 3652summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 3653summary_info += {'module directory': qemu_moddir} 3654summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 3655summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 3656summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 3657if targetos != 'windows' 3658 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 3659 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 3660else 3661 summary_info += {'local state directory': 'queried at runtime'} 3662endif 3663summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 3664summary_info += {'Build directory': meson.current_build_dir()} 3665summary_info += {'Source path': meson.current_source_dir()} 3666summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 3667summary(summary_info, bool_yn: true, section: 'Directories') 3668 3669# Host binaries 3670summary_info = {} 3671summary_info += {'git': config_host['GIT']} 3672summary_info += {'make': config_host['MAKE']} 3673summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 3674summary_info += {'sphinx-build': sphinx_build} 3675if config_host.has_key('HAVE_GDB_BIN') 3676 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 3677endif 3678summary_info += {'iasl': iasl} 3679summary_info += {'genisoimage': config_host['GENISOIMAGE']} 3680if targetos == 'windows' and have_ga 3681 summary_info += {'wixl': wixl} 3682endif 3683if slirp_opt != 'disabled' and have_system 3684 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 3685endif 3686summary(summary_info, bool_yn: true, section: 'Host binaries') 3687 3688# Configurable features 3689summary_info = {} 3690summary_info += {'Documentation': build_docs} 3691summary_info += {'system-mode emulation': have_system} 3692summary_info += {'user-mode emulation': have_user} 3693summary_info += {'block layer': have_block} 3694summary_info += {'Install blobs': get_option('install_blobs')} 3695summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} 3696if config_host.has_key('CONFIG_MODULES') 3697 summary_info += {'alternative module path': get_option('module_upgrades')} 3698endif 3699summary_info += {'fuzzing support': get_option('fuzzing')} 3700if have_system 3701 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 3702endif 3703summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 3704if 'simple' in get_option('trace_backends') 3705 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 3706endif 3707summary_info += {'D-Bus display': dbus_display} 3708summary_info += {'QOM debugging': get_option('qom_cast_debug')} 3709summary_info += {'vhost-kernel support': have_vhost_kernel} 3710summary_info += {'vhost-net support': have_vhost_net} 3711summary_info += {'vhost-user support': have_vhost_user} 3712summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 3713summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 3714summary_info += {'vhost-vdpa support': have_vhost_vdpa} 3715summary_info += {'build guest agent': have_ga} 3716summary(summary_info, bool_yn: true, section: 'Configurable features') 3717 3718# Compilation information 3719summary_info = {} 3720summary_info += {'host CPU': cpu} 3721summary_info += {'host endianness': build_machine.endian()} 3722summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 3723summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 3724if link_language == 'cpp' 3725 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 3726else 3727 summary_info += {'C++ compiler': false} 3728endif 3729if targetos == 'darwin' 3730 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 3731endif 3732summary_info += {'CFLAGS': ' '.join(get_option('c_args') 3733 + ['-O' + get_option('optimization')] 3734 + (get_option('debug') ? ['-g'] : []))} 3735if link_language == 'cpp' 3736 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') 3737 + ['-O' + get_option('optimization')] 3738 + (get_option('debug') ? ['-g'] : []))} 3739endif 3740if targetos == 'darwin' 3741 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') 3742 + ['-O' + get_option('optimization')] 3743 + (get_option('debug') ? ['-g'] : []))} 3744endif 3745link_args = get_option(link_language + '_link_args') 3746if link_args.length() > 0 3747 summary_info += {'LDFLAGS': ' '.join(link_args)} 3748endif 3749summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)} 3750summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)} 3751summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)} 3752summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 3753summary_info += {'profiler': get_option('profiler')} 3754summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 3755summary_info += {'PIE': get_option('b_pie')} 3756summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 3757summary_info += {'malloc trim support': has_malloc_trim} 3758summary_info += {'membarrier': have_membarrier} 3759summary_info += {'debug stack usage': get_option('debug_stack_usage')} 3760summary_info += {'mutex debugging': get_option('debug_mutex')} 3761summary_info += {'memory allocator': get_option('malloc')} 3762summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 3763summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 3764summary_info += {'gprof enabled': get_option('gprof')} 3765summary_info += {'gcov': get_option('b_coverage')} 3766summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} 3767summary_info += {'CFI support': get_option('cfi')} 3768if get_option('cfi') 3769 summary_info += {'CFI debug support': get_option('cfi_debug')} 3770endif 3771summary_info += {'strip binaries': get_option('strip')} 3772summary_info += {'sparse': sparse} 3773summary_info += {'mingw32 support': targetos == 'windows'} 3774summary(summary_info, bool_yn: true, section: 'Compilation') 3775 3776# snarf the cross-compilation information for tests 3777summary_info = {} 3778have_cross = false 3779foreach target: target_dirs 3780 tcg_mak = meson.current_build_dir() / 'tests/tcg' / 'config-' + target + '.mak' 3781 if fs.exists(tcg_mak) 3782 config_cross_tcg = keyval.load(tcg_mak) 3783 if 'CC' in config_cross_tcg 3784 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 3785 have_cross = true 3786 endif 3787 endif 3788endforeach 3789if have_cross 3790 summary(summary_info, bool_yn: true, section: 'Cross compilers') 3791endif 3792 3793# Targets and accelerators 3794summary_info = {} 3795if have_system 3796 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 3797 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 3798 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 3799 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 3800 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')} 3801 summary_info += {'Xen support': xen.found()} 3802 if xen.found() 3803 summary_info += {'xen ctrl version': xen.version()} 3804 endif 3805endif 3806summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 3807if config_all.has_key('CONFIG_TCG') 3808 if get_option('tcg_interpreter') 3809 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 3810 else 3811 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 3812 endif 3813 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')} 3814 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 3815endif 3816summary_info += {'target list': ' '.join(target_dirs)} 3817if have_system 3818 summary_info += {'default devices': get_option('default_devices')} 3819 summary_info += {'out of process emulation': multiprocess_allowed} 3820 summary_info += {'vfio-user server': vfio_user_server_allowed} 3821endif 3822summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 3823 3824# Block layer 3825summary_info = {} 3826summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} 3827summary_info += {'coroutine pool': have_coroutine_pool} 3828if have_block 3829 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 3830 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 3831 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 3832 summary_info += {'VirtFS support': have_virtfs} 3833 summary_info += {'build virtiofs daemon': have_virtiofsd} 3834 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')} 3835 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 3836 summary_info += {'bochs support': get_option('bochs').allowed()} 3837 summary_info += {'cloop support': get_option('cloop').allowed()} 3838 summary_info += {'dmg support': get_option('dmg').allowed()} 3839 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 3840 summary_info += {'vdi support': get_option('vdi').allowed()} 3841 summary_info += {'vvfat support': get_option('vvfat').allowed()} 3842 summary_info += {'qed support': get_option('qed').allowed()} 3843 summary_info += {'parallels support': get_option('parallels').allowed()} 3844 summary_info += {'FUSE exports': fuse} 3845endif 3846summary(summary_info, bool_yn: true, section: 'Block layer support') 3847 3848# Crypto 3849summary_info = {} 3850summary_info += {'TLS priority': get_option('tls_priority')} 3851summary_info += {'GNUTLS support': gnutls} 3852if gnutls.found() 3853 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 3854endif 3855summary_info += {'libgcrypt': gcrypt} 3856summary_info += {'nettle': nettle} 3857if nettle.found() 3858 summary_info += {' XTS': xts != 'private'} 3859endif 3860summary_info += {'AF_ALG support': have_afalg} 3861summary_info += {'rng-none': get_option('rng_none')} 3862summary_info += {'Linux keyring': have_keyring} 3863summary(summary_info, bool_yn: true, section: 'Crypto') 3864 3865# Libraries 3866summary_info = {} 3867if targetos == 'darwin' 3868 summary_info += {'Cocoa support': cocoa} 3869 summary_info += {'vmnet.framework support': vmnet} 3870endif 3871summary_info += {'SDL support': sdl} 3872summary_info += {'SDL image support': sdl_image} 3873summary_info += {'GTK support': gtk} 3874summary_info += {'pixman': pixman} 3875summary_info += {'VTE support': vte} 3876summary_info += {'slirp support': slirp_opt == 'internal' ? slirp_opt : slirp} 3877summary_info += {'libtasn1': tasn1} 3878summary_info += {'PAM': pam} 3879summary_info += {'iconv support': iconv} 3880summary_info += {'curses support': curses} 3881summary_info += {'virgl support': virgl} 3882summary_info += {'curl support': curl} 3883summary_info += {'Multipath support': mpathpersist} 3884summary_info += {'PNG support': png} 3885summary_info += {'VNC support': vnc} 3886if vnc.found() 3887 summary_info += {'VNC SASL support': sasl} 3888 summary_info += {'VNC JPEG support': jpeg} 3889endif 3890if targetos not in ['darwin', 'haiku', 'windows'] 3891 summary_info += {'OSS support': oss} 3892elif targetos == 'darwin' 3893 summary_info += {'CoreAudio support': coreaudio} 3894elif targetos == 'windows' 3895 summary_info += {'DirectSound support': dsound} 3896endif 3897if targetos == 'linux' 3898 summary_info += {'ALSA support': alsa} 3899 summary_info += {'PulseAudio support': pulse} 3900endif 3901summary_info += {'JACK support': jack} 3902summary_info += {'brlapi support': brlapi} 3903summary_info += {'vde support': vde} 3904summary_info += {'netmap support': have_netmap} 3905summary_info += {'l2tpv3 support': have_l2tpv3} 3906summary_info += {'Linux AIO support': libaio} 3907summary_info += {'Linux io_uring support': linux_io_uring} 3908summary_info += {'ATTR/XATTR support': libattr} 3909summary_info += {'RDMA support': rdma} 3910summary_info += {'PVRDMA support': have_pvrdma} 3911summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 3912summary_info += {'libcap-ng support': libcap_ng} 3913summary_info += {'bpf support': libbpf} 3914summary_info += {'spice protocol support': spice_protocol} 3915if spice_protocol.found() 3916 summary_info += {' spice server support': spice} 3917endif 3918summary_info += {'rbd support': rbd} 3919summary_info += {'smartcard support': cacard} 3920summary_info += {'U2F support': u2f} 3921summary_info += {'libusb': libusb} 3922summary_info += {'usb net redir': usbredir} 3923summary_info += {'OpenGL support (epoxy)': opengl} 3924summary_info += {'GBM': gbm} 3925summary_info += {'libiscsi support': libiscsi} 3926summary_info += {'libnfs support': libnfs} 3927if targetos == 'windows' 3928 if have_ga 3929 summary_info += {'QGA VSS support': have_qga_vss} 3930 endif 3931endif 3932summary_info += {'seccomp support': seccomp} 3933summary_info += {'GlusterFS support': glusterfs} 3934summary_info += {'TPM support': have_tpm} 3935summary_info += {'libssh support': libssh} 3936summary_info += {'lzo support': lzo} 3937summary_info += {'snappy support': snappy} 3938summary_info += {'bzip2 support': libbzip2} 3939summary_info += {'lzfse support': liblzfse} 3940summary_info += {'zstd support': zstd} 3941summary_info += {'NUMA host support': numa} 3942summary_info += {'capstone': capstone} 3943summary_info += {'libpmem support': libpmem} 3944summary_info += {'libdaxctl support': libdaxctl} 3945summary_info += {'libudev': libudev} 3946# Dummy dependency, keep .found() 3947summary_info += {'FUSE lseek': fuse_lseek.found()} 3948summary_info += {'selinux': selinux} 3949summary(summary_info, bool_yn: true, section: 'Dependencies') 3950 3951if not supported_cpus.contains(cpu) 3952 message() 3953 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 3954 message() 3955 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 3956 message('The QEMU project intends to remove support for this host CPU in') 3957 message('a future release if nobody volunteers to maintain it and to') 3958 message('provide a build host for our continuous integration setup.') 3959 message('configure has succeeded and you can continue to build, but') 3960 message('if you care about QEMU on this platform you should contact') 3961 message('us upstream at qemu-devel@nongnu.org.') 3962endif 3963 3964if not supported_oses.contains(targetos) 3965 message() 3966 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 3967 message() 3968 message('Host OS ' + targetos + 'support is not currently maintained.') 3969 message('The QEMU project intends to remove support for this host OS in') 3970 message('a future release if nobody volunteers to maintain it and to') 3971 message('provide a build host for our continuous integration setup.') 3972 message('configure has succeeded and you can continue to build, but') 3973 message('if you care about QEMU on this platform you should contact') 3974 message('us upstream at qemu-devel@nongnu.org.') 3975endif 3976