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