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