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