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 'gdbstub', 2867] 2868if have_linux_user 2869 trace_events_subdirs += [ 'linux-user' ] 2870endif 2871if have_bsd_user 2872 trace_events_subdirs += [ 'bsd-user' ] 2873endif 2874if have_block 2875 trace_events_subdirs += [ 2876 'authz', 2877 'block', 2878 'io', 2879 'nbd', 2880 'scsi', 2881 ] 2882endif 2883if have_system 2884 trace_events_subdirs += [ 2885 'accel/kvm', 2886 'audio', 2887 'backends', 2888 'backends/tpm', 2889 'chardev', 2890 'ebpf', 2891 'hw/9pfs', 2892 'hw/acpi', 2893 'hw/adc', 2894 'hw/alpha', 2895 'hw/arm', 2896 'hw/audio', 2897 'hw/block', 2898 'hw/block/dataplane', 2899 'hw/char', 2900 'hw/display', 2901 'hw/dma', 2902 'hw/hyperv', 2903 'hw/i2c', 2904 'hw/i386', 2905 'hw/i386/xen', 2906 'hw/ide', 2907 'hw/input', 2908 'hw/intc', 2909 'hw/isa', 2910 'hw/mem', 2911 'hw/mips', 2912 'hw/misc', 2913 'hw/misc/macio', 2914 'hw/net', 2915 'hw/net/can', 2916 'hw/nubus', 2917 'hw/nvme', 2918 'hw/nvram', 2919 'hw/pci', 2920 'hw/pci-host', 2921 'hw/ppc', 2922 'hw/rdma', 2923 'hw/rdma/vmw', 2924 'hw/rtc', 2925 'hw/s390x', 2926 'hw/scsi', 2927 'hw/sd', 2928 'hw/sh4', 2929 'hw/sparc', 2930 'hw/sparc64', 2931 'hw/ssi', 2932 'hw/timer', 2933 'hw/tpm', 2934 'hw/usb', 2935 'hw/vfio', 2936 'hw/virtio', 2937 'hw/watchdog', 2938 'hw/xen', 2939 'hw/gpio', 2940 'migration', 2941 'net', 2942 'softmmu', 2943 'ui', 2944 'hw/remote', 2945 ] 2946endif 2947if have_system or have_user 2948 trace_events_subdirs += [ 2949 'accel/tcg', 2950 'hw/core', 2951 'target/arm', 2952 'target/arm/hvf', 2953 'target/hppa', 2954 'target/i386', 2955 'target/i386/kvm', 2956 'target/mips/tcg', 2957 'target/nios2', 2958 'target/ppc', 2959 'target/riscv', 2960 'target/s390x', 2961 'target/s390x/kvm', 2962 'target/sparc', 2963 ] 2964endif 2965 2966vhost_user = not_found 2967if targetos == 'linux' and have_vhost_user 2968 libvhost_user = subproject('libvhost-user') 2969 vhost_user = libvhost_user.get_variable('vhost_user_dep') 2970endif 2971 2972libvduse = not_found 2973if have_libvduse 2974 libvduse_proj = subproject('libvduse') 2975 libvduse = libvduse_proj.get_variable('libvduse_dep') 2976endif 2977 2978# NOTE: the trace/ subdirectory needs the qapi_trace_events variable 2979# that is filled in by qapi/. 2980subdir('qapi') 2981subdir('qobject') 2982subdir('stubs') 2983subdir('trace') 2984subdir('util') 2985subdir('qom') 2986subdir('authz') 2987subdir('crypto') 2988subdir('ui') 2989subdir('hw') 2990subdir('gdbstub') 2991 2992 2993if enable_modules 2994 libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO') 2995 modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO') 2996endif 2997 2998qom_ss = qom_ss.apply(config_host, strict: false) 2999libqom = static_library('qom', qom_ss.sources() + genh, 3000 dependencies: [qom_ss.dependencies()], 3001 name_suffix: 'fa') 3002qom = declare_dependency(link_whole: libqom) 3003 3004event_loop_base = files('event-loop-base.c') 3005event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh, 3006 build_by_default: true) 3007event_loop_base = declare_dependency(link_whole: event_loop_base, 3008 dependencies: [qom]) 3009 3010stub_ss = stub_ss.apply(config_all, strict: false) 3011 3012util_ss.add_all(trace_ss) 3013util_ss = util_ss.apply(config_all, strict: false) 3014libqemuutil = static_library('qemuutil', 3015 sources: util_ss.sources() + stub_ss.sources() + genh, 3016 dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman]) 3017qemuutil = declare_dependency(link_with: libqemuutil, 3018 sources: genh + version_res, 3019 dependencies: [event_loop_base]) 3020 3021if have_system or have_user 3022 decodetree = generator(find_program('scripts/decodetree.py'), 3023 output: 'decode-@BASENAME@.c.inc', 3024 arguments: ['@INPUT@', '@EXTRA_ARGS@', '-o', '@OUTPUT@']) 3025 subdir('libdecnumber') 3026 subdir('target') 3027endif 3028 3029subdir('audio') 3030subdir('io') 3031subdir('chardev') 3032subdir('fsdev') 3033subdir('dump') 3034 3035if have_block 3036 block_ss.add(files( 3037 'block.c', 3038 'blockjob.c', 3039 'job.c', 3040 'qemu-io-cmds.c', 3041 )) 3042 if config_host_data.get('CONFIG_REPLICATION') 3043 block_ss.add(files('replication.c')) 3044 endif 3045 3046 subdir('nbd') 3047 subdir('scsi') 3048 subdir('block') 3049 3050 blockdev_ss.add(files( 3051 'blockdev.c', 3052 'blockdev-nbd.c', 3053 'iothread.c', 3054 'job-qmp.c', 3055 ), gnutls) 3056 3057 # os-posix.c contains POSIX-specific functions used by qemu-storage-daemon, 3058 # os-win32.c does not 3059 blockdev_ss.add(when: 'CONFIG_POSIX', if_true: files('os-posix.c')) 3060 softmmu_ss.add(when: 'CONFIG_WIN32', if_true: [files('os-win32.c')]) 3061endif 3062 3063common_ss.add(files('cpus-common.c')) 3064 3065subdir('softmmu') 3066 3067common_ss.add(capstone) 3068specific_ss.add(files('cpu.c', 'disas.c'), capstone) 3069 3070# Work around a gcc bug/misfeature wherein constant propagation looks 3071# through an alias: 3072# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99696 3073# to guess that a const variable is always zero. Without lto, this is 3074# impossible, as the alias is restricted to page-vary-common.c. Indeed, 3075# without lto, not even the alias is required -- we simply use different 3076# declarations in different compilation units. 3077pagevary = files('page-vary-common.c') 3078if get_option('b_lto') 3079 pagevary_flags = ['-fno-lto'] 3080 if get_option('cfi') 3081 pagevary_flags += '-fno-sanitize=cfi-icall' 3082 endif 3083 pagevary = static_library('page-vary-common', sources: pagevary + genh, 3084 c_args: pagevary_flags) 3085 pagevary = declare_dependency(link_with: pagevary) 3086endif 3087common_ss.add(pagevary) 3088specific_ss.add(files('page-vary.c')) 3089 3090subdir('backends') 3091subdir('disas') 3092subdir('migration') 3093subdir('monitor') 3094subdir('net') 3095subdir('replay') 3096subdir('semihosting') 3097subdir('tcg') 3098subdir('fpu') 3099subdir('accel') 3100subdir('plugins') 3101subdir('ebpf') 3102 3103common_user_inc = [] 3104 3105subdir('common-user') 3106subdir('bsd-user') 3107subdir('linux-user') 3108 3109# needed for fuzzing binaries 3110subdir('tests/qtest/libqos') 3111subdir('tests/qtest/fuzz') 3112 3113# accel modules 3114tcg_real_module_ss = ss.source_set() 3115tcg_real_module_ss.add_all(when: 'CONFIG_TCG_MODULAR', if_true: tcg_module_ss) 3116specific_ss.add_all(when: 'CONFIG_TCG_BUILTIN', if_true: tcg_module_ss) 3117target_modules += { 'accel' : { 'qtest': qtest_module_ss, 3118 'tcg': tcg_real_module_ss }} 3119 3120######################## 3121# Library dependencies # 3122######################## 3123 3124modinfo_collect = find_program('scripts/modinfo-collect.py') 3125modinfo_generate = find_program('scripts/modinfo-generate.py') 3126modinfo_files = [] 3127 3128block_mods = [] 3129softmmu_mods = [] 3130foreach d, list : modules 3131 foreach m, module_ss : list 3132 if enable_modules and targetos != 'windows' 3133 module_ss = module_ss.apply(config_all, strict: false) 3134 sl = static_library(d + '-' + m, [genh, module_ss.sources()], 3135 dependencies: [modulecommon, module_ss.dependencies()], pic: true) 3136 if d == 'block' 3137 block_mods += sl 3138 else 3139 softmmu_mods += sl 3140 endif 3141 if module_ss.sources() != [] 3142 # FIXME: Should use sl.extract_all_objects(recursive: true) as 3143 # input. Sources can be used multiple times but objects are 3144 # unique when it comes to lookup in compile_commands.json. 3145 # Depnds on a mesion version with 3146 # https://github.com/mesonbuild/meson/pull/8900 3147 modinfo_files += custom_target(d + '-' + m + '.modinfo', 3148 output: d + '-' + m + '.modinfo', 3149 input: module_ss.sources() + genh, 3150 capture: true, 3151 command: [modinfo_collect, module_ss.sources()]) 3152 endif 3153 else 3154 if d == 'block' 3155 block_ss.add_all(module_ss) 3156 else 3157 softmmu_ss.add_all(module_ss) 3158 endif 3159 endif 3160 endforeach 3161endforeach 3162 3163foreach d, list : target_modules 3164 foreach m, module_ss : list 3165 if enable_modules and targetos != 'windows' 3166 foreach target : target_dirs 3167 if target.endswith('-softmmu') 3168 config_target = config_target_mak[target] 3169 config_target += config_host 3170 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3171 c_args = ['-DNEED_CPU_H', 3172 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3173 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3174 target_module_ss = module_ss.apply(config_target, strict: false) 3175 if target_module_ss.sources() != [] 3176 module_name = d + '-' + m + '-' + config_target['TARGET_NAME'] 3177 sl = static_library(module_name, 3178 [genh, target_module_ss.sources()], 3179 dependencies: [modulecommon, target_module_ss.dependencies()], 3180 include_directories: target_inc, 3181 c_args: c_args, 3182 pic: true) 3183 softmmu_mods += sl 3184 # FIXME: Should use sl.extract_all_objects(recursive: true) too. 3185 modinfo_files += custom_target(module_name + '.modinfo', 3186 output: module_name + '.modinfo', 3187 input: target_module_ss.sources() + genh, 3188 capture: true, 3189 command: [modinfo_collect, '--target', target, target_module_ss.sources()]) 3190 endif 3191 endif 3192 endforeach 3193 else 3194 specific_ss.add_all(module_ss) 3195 endif 3196 endforeach 3197endforeach 3198 3199if enable_modules 3200 foreach target : target_dirs 3201 if target.endswith('-softmmu') 3202 config_target = config_target_mak[target] 3203 config_devices_mak = target + '-config-devices.mak' 3204 modinfo_src = custom_target('modinfo-' + target + '.c', 3205 output: 'modinfo-' + target + '.c', 3206 input: modinfo_files, 3207 command: [modinfo_generate, '--devices', config_devices_mak, '@INPUT@'], 3208 capture: true) 3209 3210 modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src) 3211 modinfo_dep = declare_dependency(link_with: modinfo_lib) 3212 3213 arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : config_target['TARGET_BASE_ARCH'] 3214 hw_arch[arch].add(modinfo_dep) 3215 endif 3216 endforeach 3217endif 3218 3219nm = find_program('nm') 3220undefsym = find_program('scripts/undefsym.py') 3221block_syms = custom_target('block.syms', output: 'block.syms', 3222 input: [libqemuutil, block_mods], 3223 capture: true, 3224 command: [undefsym, nm, '@INPUT@']) 3225qemu_syms = custom_target('qemu.syms', output: 'qemu.syms', 3226 input: [libqemuutil, softmmu_mods], 3227 capture: true, 3228 command: [undefsym, nm, '@INPUT@']) 3229 3230authz_ss = authz_ss.apply(config_host, strict: false) 3231libauthz = static_library('authz', authz_ss.sources() + genh, 3232 dependencies: [authz_ss.dependencies()], 3233 name_suffix: 'fa', 3234 build_by_default: false) 3235 3236authz = declare_dependency(link_whole: libauthz, 3237 dependencies: qom) 3238 3239crypto_ss = crypto_ss.apply(config_host, strict: false) 3240libcrypto = static_library('crypto', crypto_ss.sources() + genh, 3241 dependencies: [crypto_ss.dependencies()], 3242 name_suffix: 'fa', 3243 build_by_default: false) 3244 3245crypto = declare_dependency(link_whole: libcrypto, 3246 dependencies: [authz, qom]) 3247 3248io_ss = io_ss.apply(config_host, strict: false) 3249libio = static_library('io', io_ss.sources() + genh, 3250 dependencies: [io_ss.dependencies()], 3251 link_with: libqemuutil, 3252 name_suffix: 'fa', 3253 build_by_default: false) 3254 3255io = declare_dependency(link_whole: libio, dependencies: [crypto, qom]) 3256 3257libmigration = static_library('migration', sources: migration_files + genh, 3258 name_suffix: 'fa', 3259 build_by_default: false) 3260migration = declare_dependency(link_with: libmigration, 3261 dependencies: [zlib, qom, io]) 3262softmmu_ss.add(migration) 3263 3264block_ss = block_ss.apply(config_host, strict: false) 3265libblock = static_library('block', block_ss.sources() + genh, 3266 dependencies: block_ss.dependencies(), 3267 link_depends: block_syms, 3268 name_suffix: 'fa', 3269 build_by_default: false) 3270 3271block = declare_dependency(link_whole: [libblock], 3272 link_args: '@block.syms', 3273 dependencies: [crypto, io]) 3274 3275blockdev_ss = blockdev_ss.apply(config_host, strict: false) 3276libblockdev = static_library('blockdev', blockdev_ss.sources() + genh, 3277 dependencies: blockdev_ss.dependencies(), 3278 name_suffix: 'fa', 3279 build_by_default: false) 3280 3281blockdev = declare_dependency(link_whole: [libblockdev], 3282 dependencies: [block, event_loop_base]) 3283 3284qmp_ss = qmp_ss.apply(config_host, strict: false) 3285libqmp = static_library('qmp', qmp_ss.sources() + genh, 3286 dependencies: qmp_ss.dependencies(), 3287 name_suffix: 'fa', 3288 build_by_default: false) 3289 3290qmp = declare_dependency(link_whole: [libqmp]) 3291 3292libchardev = static_library('chardev', chardev_ss.sources() + genh, 3293 name_suffix: 'fa', 3294 dependencies: chardev_ss.dependencies(), 3295 build_by_default: false) 3296 3297chardev = declare_dependency(link_whole: libchardev) 3298 3299hwcore_ss = hwcore_ss.apply(config_host, strict: false) 3300libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, 3301 name_suffix: 'fa', 3302 build_by_default: false) 3303hwcore = declare_dependency(link_whole: libhwcore) 3304common_ss.add(hwcore) 3305 3306########### 3307# Targets # 3308########### 3309 3310emulator_modules = [] 3311foreach m : block_mods + softmmu_mods 3312 emulator_modules += shared_module(m.name(), 3313 build_by_default: true, 3314 name_prefix: '', 3315 link_whole: m, 3316 install: true, 3317 install_dir: qemu_moddir) 3318endforeach 3319if emulator_modules.length() > 0 3320 alias_target('modules', emulator_modules) 3321endif 3322 3323softmmu_ss.add(authz, blockdev, chardev, crypto, io, qmp) 3324common_ss.add(qom, qemuutil) 3325 3326common_ss.add_all(when: 'CONFIG_SOFTMMU', if_true: [softmmu_ss]) 3327common_ss.add_all(when: 'CONFIG_USER_ONLY', if_true: user_ss) 3328 3329common_all = common_ss.apply(config_all, strict: false) 3330common_all = static_library('common', 3331 build_by_default: false, 3332 sources: common_all.sources() + genh, 3333 include_directories: common_user_inc, 3334 implicit_include_directories: false, 3335 dependencies: common_all.dependencies(), 3336 name_suffix: 'fa') 3337 3338feature_to_c = find_program('scripts/feature_to_c.sh') 3339 3340if targetos == 'darwin' 3341 entitlement = find_program('scripts/entitlement.sh') 3342endif 3343 3344emulators = {} 3345foreach target : target_dirs 3346 config_target = config_target_mak[target] 3347 target_name = config_target['TARGET_NAME'] 3348 target_base_arch = config_target['TARGET_BASE_ARCH'] 3349 arch_srcs = [config_target_h[target]] 3350 arch_deps = [] 3351 c_args = ['-DNEED_CPU_H', 3352 '-DCONFIG_TARGET="@0@-config-target.h"'.format(target), 3353 '-DCONFIG_DEVICES="@0@-config-devices.h"'.format(target)] 3354 link_args = emulator_link_args 3355 3356 config_target += config_host 3357 target_inc = [include_directories('target' / config_target['TARGET_BASE_ARCH'])] 3358 if targetos == 'linux' 3359 target_inc += include_directories('linux-headers', is_system: true) 3360 endif 3361 if target.endswith('-softmmu') 3362 target_type='system' 3363 t = target_softmmu_arch[target_base_arch].apply(config_target, strict: false) 3364 arch_srcs += t.sources() 3365 arch_deps += t.dependencies() 3366 3367 hw_dir = target_name == 'sparc64' ? 'sparc64' : target_base_arch 3368 hw = hw_arch[hw_dir].apply(config_target, strict: false) 3369 arch_srcs += hw.sources() 3370 arch_deps += hw.dependencies() 3371 3372 arch_srcs += config_devices_h[target] 3373 link_args += ['@block.syms', '@qemu.syms'] 3374 else 3375 abi = config_target['TARGET_ABI_DIR'] 3376 target_type='user' 3377 target_inc += common_user_inc 3378 if target_base_arch in target_user_arch 3379 t = target_user_arch[target_base_arch].apply(config_target, strict: false) 3380 arch_srcs += t.sources() 3381 arch_deps += t.dependencies() 3382 endif 3383 if 'CONFIG_LINUX_USER' in config_target 3384 base_dir = 'linux-user' 3385 endif 3386 if 'CONFIG_BSD_USER' in config_target 3387 base_dir = 'bsd-user' 3388 target_inc += include_directories('bsd-user/' / targetos) 3389 target_inc += include_directories('bsd-user/host/' / host_arch) 3390 dir = base_dir / abi 3391 arch_srcs += files(dir / 'signal.c', dir / 'target_arch_cpu.c') 3392 endif 3393 target_inc += include_directories( 3394 base_dir, 3395 base_dir / abi, 3396 ) 3397 if 'CONFIG_LINUX_USER' in config_target 3398 dir = base_dir / abi 3399 arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c') 3400 if config_target.has_key('TARGET_SYSTBL_ABI') 3401 arch_srcs += \ 3402 syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'], 3403 extra_args : config_target['TARGET_SYSTBL_ABI']) 3404 endif 3405 endif 3406 endif 3407 3408 if 'TARGET_XML_FILES' in config_target 3409 gdbstub_xml = custom_target(target + '-gdbstub-xml.c', 3410 output: target + '-gdbstub-xml.c', 3411 input: files(config_target['TARGET_XML_FILES'].split()), 3412 command: [feature_to_c, '@INPUT@'], 3413 capture: true) 3414 arch_srcs += gdbstub_xml 3415 endif 3416 3417 t = target_arch[target_base_arch].apply(config_target, strict: false) 3418 arch_srcs += t.sources() 3419 arch_deps += t.dependencies() 3420 3421 target_common = common_ss.apply(config_target, strict: false) 3422 objects = common_all.extract_objects(target_common.sources()) 3423 deps = target_common.dependencies() 3424 3425 target_specific = specific_ss.apply(config_target, strict: false) 3426 arch_srcs += target_specific.sources() 3427 arch_deps += target_specific.dependencies() 3428 3429 lib = static_library('qemu-' + target, 3430 sources: arch_srcs + genh, 3431 dependencies: arch_deps, 3432 objects: objects, 3433 include_directories: target_inc, 3434 c_args: c_args, 3435 build_by_default: false, 3436 name_suffix: 'fa') 3437 3438 if target.endswith('-softmmu') 3439 execs = [{ 3440 'name': 'qemu-system-' + target_name, 3441 'win_subsystem': 'console', 3442 'sources': files('softmmu/main.c'), 3443 'dependencies': [] 3444 }] 3445 if targetos == 'windows' and (sdl.found() or gtk.found()) 3446 execs += [{ 3447 'name': 'qemu-system-' + target_name + 'w', 3448 'win_subsystem': 'windows', 3449 'sources': files('softmmu/main.c'), 3450 'dependencies': [] 3451 }] 3452 endif 3453 if get_option('fuzzing') 3454 specific_fuzz = specific_fuzz_ss.apply(config_target, strict: false) 3455 execs += [{ 3456 'name': 'qemu-fuzz-' + target_name, 3457 'win_subsystem': 'console', 3458 'sources': specific_fuzz.sources(), 3459 'dependencies': specific_fuzz.dependencies(), 3460 }] 3461 endif 3462 else 3463 execs = [{ 3464 'name': 'qemu-' + target_name, 3465 'win_subsystem': 'console', 3466 'sources': [], 3467 'dependencies': [] 3468 }] 3469 endif 3470 foreach exe: execs 3471 exe_name = exe['name'] 3472 if targetos == 'darwin' 3473 exe_name += '-unsigned' 3474 endif 3475 3476 emulator = executable(exe_name, exe['sources'], 3477 install: true, 3478 c_args: c_args, 3479 dependencies: arch_deps + deps + exe['dependencies'], 3480 objects: lib.extract_all_objects(recursive: true), 3481 link_language: link_language, 3482 link_depends: [block_syms, qemu_syms] + exe.get('link_depends', []), 3483 link_args: link_args, 3484 win_subsystem: exe['win_subsystem']) 3485 3486 if targetos == 'darwin' 3487 icon = 'pc-bios/qemu.rsrc' 3488 build_input = [emulator, files(icon)] 3489 install_input = [ 3490 get_option('bindir') / exe_name, 3491 meson.current_source_dir() / icon 3492 ] 3493 if 'CONFIG_HVF' in config_target 3494 entitlements = 'accel/hvf/entitlements.plist' 3495 build_input += files(entitlements) 3496 install_input += meson.current_source_dir() / entitlements 3497 endif 3498 3499 emulators += {exe['name'] : custom_target(exe['name'], 3500 input: build_input, 3501 output: exe['name'], 3502 command: [entitlement, '@OUTPUT@', '@INPUT@']) 3503 } 3504 3505 meson.add_install_script(entitlement, '--install', 3506 get_option('bindir') / exe['name'], 3507 install_input) 3508 else 3509 emulators += {exe['name']: emulator} 3510 endif 3511 3512 if stap.found() 3513 foreach stp: [ 3514 {'ext': '.stp-build', 'fmt': 'stap', 'bin': meson.current_build_dir() / exe['name'], 'install': false}, 3515 {'ext': '.stp', 'fmt': 'stap', 'bin': get_option('prefix') / get_option('bindir') / exe['name'], 'install': true}, 3516 {'ext': '-simpletrace.stp', 'fmt': 'simpletrace-stap', 'bin': '', 'install': true}, 3517 {'ext': '-log.stp', 'fmt': 'log-stap', 'bin': '', 'install': true}, 3518 ] 3519 custom_target(exe['name'] + stp['ext'], 3520 input: trace_events_all, 3521 output: exe['name'] + stp['ext'], 3522 install: stp['install'], 3523 install_dir: get_option('datadir') / 'systemtap/tapset', 3524 command: [ 3525 tracetool, '--group=all', '--format=' + stp['fmt'], 3526 '--binary=' + stp['bin'], 3527 '--target-name=' + target_name, 3528 '--target-type=' + target_type, 3529 '--probe-prefix=qemu.' + target_type + '.' + target_name, 3530 '@INPUT@', '@OUTPUT@' 3531 ], 3532 depend_files: tracetool_depends) 3533 endforeach 3534 endif 3535 endforeach 3536endforeach 3537 3538# Other build targets 3539 3540if 'CONFIG_PLUGIN' in config_host 3541 install_headers('include/qemu/qemu-plugin.h') 3542endif 3543 3544subdir('qga') 3545 3546# Don't build qemu-keymap if xkbcommon is not explicitly enabled 3547# when we don't build tools or system 3548if xkbcommon.found() 3549 # used for the update-keymaps target, so include rules even if !have_tools 3550 qemu_keymap = executable('qemu-keymap', files('qemu-keymap.c', 'ui/input-keymap.c') + genh, 3551 dependencies: [qemuutil, xkbcommon], install: have_tools) 3552endif 3553 3554if have_tools 3555 qemu_img = executable('qemu-img', [files('qemu-img.c'), hxdep], 3556 dependencies: [authz, block, crypto, io, qom, qemuutil], install: true) 3557 qemu_io = executable('qemu-io', files('qemu-io.c'), 3558 dependencies: [block, qemuutil], install: true) 3559 qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'), 3560 dependencies: [blockdev, qemuutil, gnutls, selinux], 3561 install: true) 3562 3563 subdir('storage-daemon') 3564 subdir('contrib/rdmacm-mux') 3565 subdir('contrib/elf2dmp') 3566 3567 executable('qemu-edid', files('qemu-edid.c', 'hw/display/edid-generate.c'), 3568 dependencies: qemuutil, 3569 install: true) 3570 3571 if have_vhost_user 3572 subdir('contrib/vhost-user-blk') 3573 subdir('contrib/vhost-user-gpu') 3574 subdir('contrib/vhost-user-input') 3575 subdir('contrib/vhost-user-scsi') 3576 endif 3577 3578 if targetos == 'linux' 3579 executable('qemu-bridge-helper', files('qemu-bridge-helper.c'), 3580 dependencies: [qemuutil, libcap_ng], 3581 install: true, 3582 install_dir: get_option('libexecdir')) 3583 3584 executable('qemu-pr-helper', files('scsi/qemu-pr-helper.c', 'scsi/utils.c'), 3585 dependencies: [authz, crypto, io, qom, qemuutil, 3586 libcap_ng, mpathpersist], 3587 install: true) 3588 endif 3589 3590 if have_ivshmem 3591 subdir('contrib/ivshmem-client') 3592 subdir('contrib/ivshmem-server') 3593 endif 3594endif 3595 3596subdir('scripts') 3597subdir('tools') 3598subdir('pc-bios') 3599subdir('docs') 3600subdir('tests') 3601if gtk.found() 3602 subdir('po') 3603endif 3604 3605if host_machine.system() == 'windows' 3606 nsis_cmd = [ 3607 find_program('scripts/nsis.py'), 3608 '@OUTPUT@', 3609 get_option('prefix'), 3610 meson.current_source_dir(), 3611 host_machine.cpu(), 3612 '--', 3613 '-DDISPLAYVERSION=' + meson.project_version(), 3614 ] 3615 if build_docs 3616 nsis_cmd += '-DCONFIG_DOCUMENTATION=y' 3617 endif 3618 if gtk.found() 3619 nsis_cmd += '-DCONFIG_GTK=y' 3620 endif 3621 3622 nsis = custom_target('nsis', 3623 output: 'qemu-setup-' + meson.project_version() + '.exe', 3624 input: files('qemu.nsi'), 3625 build_always_stale: true, 3626 command: nsis_cmd + ['@INPUT@']) 3627 alias_target('installer', nsis) 3628endif 3629 3630######################### 3631# Configuration summary # 3632######################### 3633 3634# Directories 3635summary_info = {} 3636summary_info += {'Install prefix': get_option('prefix')} 3637summary_info += {'BIOS directory': qemu_datadir} 3638pathsep = targetos == 'windows' ? ';' : ':' 3639summary_info += {'firmware path': pathsep.join(get_option('qemu_firmwarepath'))} 3640summary_info += {'binary directory': get_option('prefix') / get_option('bindir')} 3641summary_info += {'library directory': get_option('prefix') / get_option('libdir')} 3642summary_info += {'module directory': qemu_moddir} 3643summary_info += {'libexec directory': get_option('prefix') / get_option('libexecdir')} 3644summary_info += {'include directory': get_option('prefix') / get_option('includedir')} 3645summary_info += {'config directory': get_option('prefix') / get_option('sysconfdir')} 3646if targetos != 'windows' 3647 summary_info += {'local state directory': get_option('prefix') / get_option('localstatedir')} 3648 summary_info += {'Manual directory': get_option('prefix') / get_option('mandir')} 3649else 3650 summary_info += {'local state directory': 'queried at runtime'} 3651endif 3652summary_info += {'Doc directory': get_option('prefix') / get_option('docdir')} 3653summary_info += {'Build directory': meson.current_build_dir()} 3654summary_info += {'Source path': meson.current_source_dir()} 3655summary_info += {'GIT submodules': config_host['GIT_SUBMODULES']} 3656summary(summary_info, bool_yn: true, section: 'Directories') 3657 3658# Host binaries 3659summary_info = {} 3660summary_info += {'git': config_host['GIT']} 3661summary_info += {'make': config_host['MAKE']} 3662summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())} 3663summary_info += {'sphinx-build': sphinx_build} 3664if config_host.has_key('HAVE_GDB_BIN') 3665 summary_info += {'gdb': config_host['HAVE_GDB_BIN']} 3666endif 3667summary_info += {'iasl': iasl} 3668summary_info += {'genisoimage': config_host['GENISOIMAGE']} 3669if targetos == 'windows' and have_ga 3670 summary_info += {'wixl': wixl} 3671endif 3672if slirp.found() and have_system 3673 summary_info += {'smbd': have_slirp_smbd ? smbd_path : false} 3674endif 3675summary(summary_info, bool_yn: true, section: 'Host binaries') 3676 3677# Configurable features 3678summary_info = {} 3679summary_info += {'Documentation': build_docs} 3680summary_info += {'system-mode emulation': have_system} 3681summary_info += {'user-mode emulation': have_user} 3682summary_info += {'block layer': have_block} 3683summary_info += {'Install blobs': get_option('install_blobs')} 3684summary_info += {'module support': config_host.has_key('CONFIG_MODULES')} 3685if config_host.has_key('CONFIG_MODULES') 3686 summary_info += {'alternative module path': get_option('module_upgrades')} 3687endif 3688summary_info += {'fuzzing support': get_option('fuzzing')} 3689if have_system 3690 summary_info += {'Audio drivers': ' '.join(audio_drivers_selected)} 3691endif 3692summary_info += {'Trace backends': ','.join(get_option('trace_backends'))} 3693if 'simple' in get_option('trace_backends') 3694 summary_info += {'Trace output file': get_option('trace_file') + '-<pid>'} 3695endif 3696summary_info += {'D-Bus display': dbus_display} 3697summary_info += {'QOM debugging': get_option('qom_cast_debug')} 3698summary_info += {'vhost-kernel support': have_vhost_kernel} 3699summary_info += {'vhost-net support': have_vhost_net} 3700summary_info += {'vhost-user support': have_vhost_user} 3701summary_info += {'vhost-user-crypto support': have_vhost_user_crypto} 3702summary_info += {'vhost-user-blk server support': have_vhost_user_blk_server} 3703summary_info += {'vhost-vdpa support': have_vhost_vdpa} 3704summary_info += {'build guest agent': have_ga} 3705summary(summary_info, bool_yn: true, section: 'Configurable features') 3706 3707# Compilation information 3708summary_info = {} 3709summary_info += {'host CPU': cpu} 3710summary_info += {'host endianness': build_machine.endian()} 3711summary_info += {'C compiler': ' '.join(meson.get_compiler('c').cmd_array())} 3712summary_info += {'Host C compiler': ' '.join(meson.get_compiler('c', native: true).cmd_array())} 3713if link_language == 'cpp' 3714 summary_info += {'C++ compiler': ' '.join(meson.get_compiler('cpp').cmd_array())} 3715else 3716 summary_info += {'C++ compiler': false} 3717endif 3718if targetos == 'darwin' 3719 summary_info += {'Objective-C compiler': ' '.join(meson.get_compiler('objc').cmd_array())} 3720endif 3721summary_info += {'CFLAGS': ' '.join(get_option('c_args') 3722 + ['-O' + get_option('optimization')] 3723 + (get_option('debug') ? ['-g'] : []))} 3724if link_language == 'cpp' 3725 summary_info += {'CXXFLAGS': ' '.join(get_option('cpp_args') 3726 + ['-O' + get_option('optimization')] 3727 + (get_option('debug') ? ['-g'] : []))} 3728endif 3729if targetos == 'darwin' 3730 summary_info += {'OBJCFLAGS': ' '.join(get_option('objc_args') 3731 + ['-O' + get_option('optimization')] 3732 + (get_option('debug') ? ['-g'] : []))} 3733endif 3734link_args = get_option(link_language + '_link_args') 3735if link_args.length() > 0 3736 summary_info += {'LDFLAGS': ' '.join(link_args)} 3737endif 3738summary_info += {'QEMU_CFLAGS': ' '.join(qemu_cflags)} 3739summary_info += {'QEMU_CXXFLAGS': ' '.join(qemu_cxxflags)} 3740summary_info += {'QEMU_OBJCFLAGS': ' '.join(qemu_objcflags)} 3741summary_info += {'QEMU_LDFLAGS': ' '.join(qemu_ldflags)} 3742summary_info += {'profiler': get_option('profiler')} 3743summary_info += {'link-time optimization (LTO)': get_option('b_lto')} 3744summary_info += {'PIE': get_option('b_pie')} 3745summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} 3746summary_info += {'malloc trim support': has_malloc_trim} 3747summary_info += {'membarrier': have_membarrier} 3748summary_info += {'debug stack usage': get_option('debug_stack_usage')} 3749summary_info += {'mutex debugging': get_option('debug_mutex')} 3750summary_info += {'memory allocator': get_option('malloc')} 3751summary_info += {'avx2 optimization': config_host_data.get('CONFIG_AVX2_OPT')} 3752summary_info += {'avx512f optimization': config_host_data.get('CONFIG_AVX512F_OPT')} 3753summary_info += {'gprof enabled': get_option('gprof')} 3754summary_info += {'gcov': get_option('b_coverage')} 3755summary_info += {'thread sanitizer': config_host.has_key('CONFIG_TSAN')} 3756summary_info += {'CFI support': get_option('cfi')} 3757if get_option('cfi') 3758 summary_info += {'CFI debug support': get_option('cfi_debug')} 3759endif 3760summary_info += {'strip binaries': get_option('strip')} 3761summary_info += {'sparse': sparse} 3762summary_info += {'mingw32 support': targetos == 'windows'} 3763summary(summary_info, bool_yn: true, section: 'Compilation') 3764 3765# snarf the cross-compilation information for tests 3766summary_info = {} 3767have_cross = false 3768foreach target: target_dirs 3769 tcg_mak = meson.current_build_dir() / 'tests/tcg' / target / 'config-target.mak' 3770 if fs.exists(tcg_mak) 3771 config_cross_tcg = keyval.load(tcg_mak) 3772 if 'CC' in config_cross_tcg 3773 summary_info += {config_cross_tcg['TARGET_NAME']: config_cross_tcg['CC']} 3774 have_cross = true 3775 endif 3776 endif 3777endforeach 3778if have_cross 3779 summary(summary_info, bool_yn: true, section: 'Cross compilers') 3780endif 3781 3782# Targets and accelerators 3783summary_info = {} 3784if have_system 3785 summary_info += {'KVM support': config_all.has_key('CONFIG_KVM')} 3786 summary_info += {'HAX support': config_all.has_key('CONFIG_HAX')} 3787 summary_info += {'HVF support': config_all.has_key('CONFIG_HVF')} 3788 summary_info += {'WHPX support': config_all.has_key('CONFIG_WHPX')} 3789 summary_info += {'NVMM support': config_all.has_key('CONFIG_NVMM')} 3790 summary_info += {'Xen support': xen.found()} 3791 if xen.found() 3792 summary_info += {'xen ctrl version': xen.version()} 3793 endif 3794endif 3795summary_info += {'TCG support': config_all.has_key('CONFIG_TCG')} 3796if config_all.has_key('CONFIG_TCG') 3797 if get_option('tcg_interpreter') 3798 summary_info += {'TCG backend': 'TCI (TCG with bytecode interpreter, slow)'} 3799 else 3800 summary_info += {'TCG backend': 'native (@0@)'.format(cpu)} 3801 endif 3802 summary_info += {'TCG plugins': config_host.has_key('CONFIG_PLUGIN')} 3803 summary_info += {'TCG debug enabled': config_host.has_key('CONFIG_DEBUG_TCG')} 3804endif 3805summary_info += {'target list': ' '.join(target_dirs)} 3806if have_system 3807 summary_info += {'default devices': get_option('default_devices')} 3808 summary_info += {'out of process emulation': multiprocess_allowed} 3809 summary_info += {'vfio-user server': vfio_user_server_allowed} 3810endif 3811summary(summary_info, bool_yn: true, section: 'Targets and accelerators') 3812 3813# Block layer 3814summary_info = {} 3815summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']} 3816summary_info += {'coroutine pool': have_coroutine_pool} 3817if have_block 3818 summary_info += {'Block whitelist (rw)': get_option('block_drv_rw_whitelist')} 3819 summary_info += {'Block whitelist (ro)': get_option('block_drv_ro_whitelist')} 3820 summary_info += {'Use block whitelist in tools': get_option('block_drv_whitelist_in_tools')} 3821 summary_info += {'VirtFS support': have_virtfs} 3822 summary_info += {'build virtiofs daemon': have_virtiofsd} 3823 summary_info += {'Live block migration': config_host_data.get('CONFIG_LIVE_BLOCK_MIGRATION')} 3824 summary_info += {'replication support': config_host_data.get('CONFIG_REPLICATION')} 3825 summary_info += {'bochs support': get_option('bochs').allowed()} 3826 summary_info += {'cloop support': get_option('cloop').allowed()} 3827 summary_info += {'dmg support': get_option('dmg').allowed()} 3828 summary_info += {'qcow v1 support': get_option('qcow1').allowed()} 3829 summary_info += {'vdi support': get_option('vdi').allowed()} 3830 summary_info += {'vvfat support': get_option('vvfat').allowed()} 3831 summary_info += {'qed support': get_option('qed').allowed()} 3832 summary_info += {'parallels support': get_option('parallels').allowed()} 3833 summary_info += {'FUSE exports': fuse} 3834 summary_info += {'VDUSE block exports': have_vduse_blk_export} 3835endif 3836summary(summary_info, bool_yn: true, section: 'Block layer support') 3837 3838# Crypto 3839summary_info = {} 3840summary_info += {'TLS priority': get_option('tls_priority')} 3841summary_info += {'GNUTLS support': gnutls} 3842if gnutls.found() 3843 summary_info += {' GNUTLS crypto': gnutls_crypto.found()} 3844endif 3845summary_info += {'libgcrypt': gcrypt} 3846summary_info += {'nettle': nettle} 3847if nettle.found() 3848 summary_info += {' XTS': xts != 'private'} 3849endif 3850summary_info += {'AF_ALG support': have_afalg} 3851summary_info += {'rng-none': get_option('rng_none')} 3852summary_info += {'Linux keyring': have_keyring} 3853summary(summary_info, bool_yn: true, section: 'Crypto') 3854 3855# Libraries 3856summary_info = {} 3857if targetos == 'darwin' 3858 summary_info += {'Cocoa support': cocoa} 3859 summary_info += {'vmnet.framework support': vmnet} 3860endif 3861summary_info += {'SDL support': sdl} 3862summary_info += {'SDL image support': sdl_image} 3863summary_info += {'GTK support': gtk} 3864summary_info += {'pixman': pixman} 3865summary_info += {'VTE support': vte} 3866summary_info += {'slirp support': slirp} 3867summary_info += {'libtasn1': tasn1} 3868summary_info += {'PAM': pam} 3869summary_info += {'iconv support': iconv} 3870summary_info += {'curses support': curses} 3871summary_info += {'virgl support': virgl} 3872summary_info += {'curl support': curl} 3873summary_info += {'Multipath support': mpathpersist} 3874summary_info += {'PNG support': png} 3875summary_info += {'VNC support': vnc} 3876if vnc.found() 3877 summary_info += {'VNC SASL support': sasl} 3878 summary_info += {'VNC JPEG support': jpeg} 3879endif 3880if targetos not in ['darwin', 'haiku', 'windows'] 3881 summary_info += {'OSS support': oss} 3882 summary_info += {'sndio support': sndio} 3883elif targetos == 'darwin' 3884 summary_info += {'CoreAudio support': coreaudio} 3885elif targetos == 'windows' 3886 summary_info += {'DirectSound support': dsound} 3887endif 3888if targetos == 'linux' 3889 summary_info += {'ALSA support': alsa} 3890 summary_info += {'PulseAudio support': pulse} 3891endif 3892summary_info += {'JACK support': jack} 3893summary_info += {'brlapi support': brlapi} 3894summary_info += {'vde support': vde} 3895summary_info += {'netmap support': have_netmap} 3896summary_info += {'l2tpv3 support': have_l2tpv3} 3897summary_info += {'Linux AIO support': libaio} 3898summary_info += {'Linux io_uring support': linux_io_uring} 3899summary_info += {'ATTR/XATTR support': libattr} 3900summary_info += {'RDMA support': rdma} 3901summary_info += {'PVRDMA support': have_pvrdma} 3902summary_info += {'fdt support': fdt_opt == 'disabled' ? false : fdt_opt} 3903summary_info += {'libcap-ng support': libcap_ng} 3904summary_info += {'bpf support': libbpf} 3905summary_info += {'spice protocol support': spice_protocol} 3906if spice_protocol.found() 3907 summary_info += {' spice server support': spice} 3908endif 3909summary_info += {'rbd support': rbd} 3910summary_info += {'smartcard support': cacard} 3911summary_info += {'U2F support': u2f} 3912summary_info += {'libusb': libusb} 3913summary_info += {'usb net redir': usbredir} 3914summary_info += {'OpenGL support (epoxy)': opengl} 3915summary_info += {'GBM': gbm} 3916summary_info += {'libiscsi support': libiscsi} 3917summary_info += {'libnfs support': libnfs} 3918if targetos == 'windows' 3919 if have_ga 3920 summary_info += {'QGA VSS support': have_qga_vss} 3921 endif 3922endif 3923summary_info += {'seccomp support': seccomp} 3924summary_info += {'GlusterFS support': glusterfs} 3925summary_info += {'TPM support': have_tpm} 3926summary_info += {'libssh support': libssh} 3927summary_info += {'lzo support': lzo} 3928summary_info += {'snappy support': snappy} 3929summary_info += {'bzip2 support': libbzip2} 3930summary_info += {'lzfse support': liblzfse} 3931summary_info += {'zstd support': zstd} 3932summary_info += {'NUMA host support': numa} 3933summary_info += {'capstone': capstone} 3934summary_info += {'libpmem support': libpmem} 3935summary_info += {'libdaxctl support': libdaxctl} 3936summary_info += {'libudev': libudev} 3937# Dummy dependency, keep .found() 3938summary_info += {'FUSE lseek': fuse_lseek.found()} 3939summary_info += {'selinux': selinux} 3940summary(summary_info, bool_yn: true, section: 'Dependencies') 3941 3942if not supported_cpus.contains(cpu) 3943 message() 3944 warning('SUPPORT FOR THIS HOST CPU WILL GO AWAY IN FUTURE RELEASES!') 3945 message() 3946 message('CPU host architecture ' + cpu + ' support is not currently maintained.') 3947 message('The QEMU project intends to remove support for this host CPU in') 3948 message('a future release if nobody volunteers to maintain it and to') 3949 message('provide a build host for our continuous integration setup.') 3950 message('configure has succeeded and you can continue to build, but') 3951 message('if you care about QEMU on this platform you should contact') 3952 message('us upstream at qemu-devel@nongnu.org.') 3953endif 3954 3955if not supported_oses.contains(targetos) 3956 message() 3957 warning('WARNING: SUPPORT FOR THIS HOST OS WILL GO AWAY IN FUTURE RELEASES!') 3958 message() 3959 message('Host OS ' + targetos + 'support is not currently maintained.') 3960 message('The QEMU project intends to remove support for this host OS in') 3961 message('a future release if nobody volunteers to maintain it and to') 3962 message('provide a build host for our continuous integration setup.') 3963 message('configure has succeeded and you can continue to build, but') 3964 message('if you care about QEMU on this platform you should contact') 3965 message('us upstream at qemu-devel@nongnu.org.') 3966endif 3967