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