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