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