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