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