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