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