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