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